From 88b390eaaf9b231ef81307f0696b82ac747430a6 Mon Sep 17 00:00:00 2001 From: tadelesh Date: Fri, 28 Jul 2023 16:43:25 +0800 Subject: [PATCH 01/13] update model base --- .../codegen/serializers/builder_serializer.py | 2 +- .../codegen/templates/model_base.py.jinja2 | 107 +++++++++++++----- .../authentication/apikey/_model_base.py | 106 ++++++++++++----- .../authentication/http/custom/_model_base.py | 106 ++++++++++++----- .../authentication/oauth2/_model_base.py | 106 ++++++++++++----- .../authentication/union/_model_base.py | 106 ++++++++++++----- .../core/internal/_model_base.py | 106 ++++++++++++----- .../_specs_/azure/core/basic/_model_base.py | 106 ++++++++++++----- .../core/basic/_operations/_operations.py | 4 +- .../core/basic/aio/_operations/_operations.py | 4 +- .../azure/core/lro/rpc/legacy/_model_base.py | 106 ++++++++++++----- .../lro/rpc/legacy/_operations/_operations.py | 2 +- .../rpc/legacy/aio/_operations/_operations.py | 2 +- .../azure/core/lro/standard/_model_base.py | 106 ++++++++++++----- .../lro/standard/_operations/_operations.py | 2 +- .../standard/aio/_operations/_operations.py | 2 +- .../_specs_/azure/core/traits/_model_base.py | 106 ++++++++++++----- .../core/traits/_operations/_operations.py | 2 +- .../traits/aio/_operations/_operations.py | 2 +- .../encode-bytes/encode/bytes/_model_base.py | 106 ++++++++++++----- .../bytes/aio/operations/_operations.py | 8 +- .../encode/bytes/operations/_operations.py | 8 +- .../encode/datetime/_model_base.py | 106 ++++++++++++----- .../datetime/aio/operations/_operations.py | 10 +- .../encode/datetime/operations/_operations.py | 10 +- .../encode/duration/_model_base.py | 106 ++++++++++++----- .../duration/aio/operations/_operations.py | 10 +- .../encode/duration/operations/_operations.py | 10 +- .../headasbooleanfalse/_model_base.py | 106 ++++++++++++----- .../_operations/_operations.py | 12 +- .../aio/_operations/_operations.py | 12 +- .../headasbooleantrue/_model_base.py | 106 ++++++++++++----- .../_operations/_operations.py | 12 +- .../aio/_operations/_operations.py | 12 +- .../parameters/bodyoptionality/_model_base.py | 106 ++++++++++++----- .../aio/operations/_operations.py | 8 +- .../bodyoptionality/operations/_operations.py | 8 +- .../collectionformat/_model_base.py | 106 ++++++++++++----- .../parameters/spread/_model_base.py | 106 ++++++++++++----- .../spread/aio/operations/_operations.py | 8 +- .../spread/operations/_operations.py | 8 +- .../projection/projectedname/_model_base.py | 106 ++++++++++++----- .../aio/operations/_operations.py | 8 +- .../projectedname/operations/_operations.py | 8 +- .../resiliency/srv/driven1/_model_base.py | 106 ++++++++++++----- .../resiliency/srv/driven2/_model_base.py | 106 ++++++++++++----- .../server/path/multiple/_model_base.py | 106 ++++++++++++----- .../server/path/single/_model_base.py | 106 ++++++++++++----- .../clientrequestid/_model_base.py | 106 ++++++++++++----- .../repeatability/_model_base.py | 106 ++++++++++++----- .../special-words/specialwords/_model_base.py | 106 ++++++++++++----- .../aio/operations/_operations.py | 2 +- .../specialwords/operations/_operations.py | 2 +- .../typetest/array/_model_base.py | 106 ++++++++++++----- .../array/aio/operations/_operations.py | 20 ++-- .../typetest/array/operations/_operations.py | 20 ++-- .../typetest/dictionary/_model_base.py | 106 ++++++++++++----- .../dictionary/aio/operations/_operations.py | 22 ++-- .../dictionary/operations/_operations.py | 22 ++-- .../typetest/enum/extensible/_model_base.py | 106 ++++++++++++----- .../extensible/_operations/_operations.py | 4 +- .../extensible/aio/_operations/_operations.py | 4 +- .../typetest/enum/fixed/_model_base.py | 106 ++++++++++++----- .../enum/fixed/_operations/_operations.py | 4 +- .../enum/fixed/aio/_operations/_operations.py | 4 +- .../typetest/model/empty/_model_base.py | 106 ++++++++++++----- .../model/empty/_operations/_operations.py | 4 +- .../empty/aio/_operations/_operations.py | 4 +- .../typetest/model/inheritance/_model_base.py | 106 ++++++++++++----- .../inheritance/_operations/_operations.py | 8 +- .../aio/_operations/_operations.py | 8 +- .../typetest/model/usage/_model_base.py | 106 ++++++++++++----- .../model/usage/_operations/_operations.py | 4 +- .../usage/aio/_operations/_operations.py | 4 +- .../typetest/model/visibility/_model_base.py | 106 ++++++++++++----- .../visibility/_operations/_operations.py | 12 +- .../visibility/aio/_operations/_operations.py | 12 +- .../typetest/property/nullable/_model_base.py | 106 ++++++++++++----- .../nullable/aio/operations/_operations.py | 24 ++-- .../nullable/operations/_operations.py | 24 ++-- .../typetest/property/optional/_model_base.py | 106 ++++++++++++----- .../optional/aio/operations/_operations.py | 28 ++--- .../optional/operations/_operations.py | 28 ++--- .../property/valuetypes/_model_base.py | 106 ++++++++++++----- .../valuetypes/aio/operations/_operations.py | 38 +++---- .../valuetypes/operations/_operations.py | 38 +++---- .../typetest/union/_model_base.py | 106 ++++++++++++----- .../typetest/union/_operations/_operations.py | 8 +- .../union/aio/_operations/_operations.py | 8 +- 89 files changed, 3230 insertions(+), 1329 deletions(-) diff --git a/packages/autorest.python/autorest/codegen/serializers/builder_serializer.py b/packages/autorest.python/autorest/codegen/serializers/builder_serializer.py index 094465775c9..1008c2da5f7 100644 --- a/packages/autorest.python/autorest/codegen/serializers/builder_serializer.py +++ b/packages/autorest.python/autorest/codegen/serializers/builder_serializer.py @@ -751,7 +751,7 @@ def _serialize_body_parameter(self, builder: OperationType) -> List[str]: elif self.code_model.options["models_mode"] == "dpg": create_body_call = ( f"_{body_kwarg_name} = json.dumps({body_param.client_name}, " - "cls=AzureJSONEncoder) # type: ignore" + "cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore" ) else: create_body_call = f"_{body_kwarg_name} = {body_param.client_name}" diff --git a/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 b/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 index 48acb463cae..587f9ee798d 100644 --- a/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 +++ b/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 @@ -16,6 +16,7 @@ import re import copy import typing import email +import json from datetime import datetime, date, time, timedelta, timezone from json import JSONEncoder import isodate @@ -128,10 +129,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +311,17 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update({ + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + }) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +537,36 @@ class Model(_MyMutableMapping): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [ + Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for x in v + ] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) \ + if hasattr(v, "as_dict") else v + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +576,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +613,8 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +629,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +792,7 @@ class _RestField: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py b/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py b/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py b/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py b/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py b/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py +++ b/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_operations/_operations.py b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_operations/_operations.py index 9190f3eafa9..f09e364dcba 100644 --- a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_operations/_operations.py +++ b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_operations/_operations.py @@ -346,7 +346,7 @@ def create_or_update(self, id: int, resource: Union[_models.User, JSON, IO], **k if isinstance(resource, (IOBase, bytes)): _content = resource else: - _content = json.dumps(resource, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_basic_create_or_update_request( id=id, @@ -492,7 +492,7 @@ def create_or_replace(self, id: int, resource: Union[_models.User, JSON, IO], ** if isinstance(resource, (IOBase, bytes)): _content = resource else: - _content = json.dumps(resource, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_basic_create_or_replace_request( id=id, diff --git a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/aio/_operations/_operations.py b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/aio/_operations/_operations.py index b5b9993886a..c04a02bbf3b 100644 --- a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/aio/_operations/_operations.py @@ -154,7 +154,7 @@ async def create_or_update(self, id: int, resource: Union[_models.User, JSON, IO if isinstance(resource, (IOBase, bytes)): _content = resource else: - _content = json.dumps(resource, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_basic_create_or_update_request( id=id, @@ -300,7 +300,7 @@ async def create_or_replace(self, id: int, resource: Union[_models.User, JSON, I if isinstance(resource, (IOBase, bytes)): _content = resource else: - _content = json.dumps(resource, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_basic_create_or_replace_request( id=id, diff --git a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_operations/_operations.py b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_operations/_operations.py index 7314466e825..4c6d89e1e84 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_operations/_operations.py +++ b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_operations/_operations.py @@ -86,7 +86,7 @@ def _create_job_initial(self, body: Union[_models.JobData, JSON, IO], **kwargs: if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_legacy_create_job_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/aio/_operations/_operations.py b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/aio/_operations/_operations.py index cb644375bea..3a86c45d268 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/aio/_operations/_operations.py @@ -61,7 +61,7 @@ async def _create_job_initial(self, body: Union[_models.JobData, JSON, IO], **kw if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_legacy_create_job_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_operations/_operations.py b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_operations/_operations.py index ed274c4520d..1dce23b9be4 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_operations/_operations.py +++ b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_operations/_operations.py @@ -140,7 +140,7 @@ def _create_or_replace_initial(self, name: str, resource: Union[_models.User, JS if isinstance(resource, (IOBase, bytes)): _content = resource else: - _content = json.dumps(resource, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_standard_create_or_replace_request( name=name, diff --git a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/aio/_operations/_operations.py b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/aio/_operations/_operations.py index faaf38333a2..baba57a788a 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/aio/_operations/_operations.py @@ -67,7 +67,7 @@ async def _create_or_replace_initial( if isinstance(resource, (IOBase, bytes)): _content = resource else: - _content = json.dumps(resource, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_standard_create_or_replace_request( name=name, diff --git a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_operations/_operations.py b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_operations/_operations.py index da6edc566ae..712cffd06d3 100644 --- a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_operations/_operations.py +++ b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_operations/_operations.py @@ -316,7 +316,7 @@ def repeatable_action( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_traits_repeatable_action_request( id=id, diff --git a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/aio/_operations/_operations.py b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/aio/_operations/_operations.py index fd95079cf63..07bd85575ed 100644 --- a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/aio/_operations/_operations.py @@ -237,7 +237,7 @@ async def repeatable_action( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_traits_repeatable_action_request( id=id, diff --git a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py +++ b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/aio/operations/_operations.py b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/aio/operations/_operations.py index bbaa55d6b6b..200d96c1f3f 100644 --- a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/aio/operations/_operations.py @@ -369,7 +369,7 @@ async def default( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_default_request( content_type=content_type, @@ -492,7 +492,7 @@ async def base64( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_base64_request( content_type=content_type, @@ -615,7 +615,7 @@ async def base64url( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_base64url_request( content_type=content_type, @@ -742,7 +742,7 @@ async def base64url_array( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_base64url_array_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/operations/_operations.py b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/operations/_operations.py index 993eb003a0f..a00f41bcec6 100644 --- a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/operations/_operations.py +++ b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/operations/_operations.py @@ -523,7 +523,7 @@ def default( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_default_request( content_type=content_type, @@ -642,7 +642,7 @@ def base64(self, body: Union[_models.Base64BytesProperty, JSON, IO], **kwargs: A if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_base64_request( content_type=content_type, @@ -765,7 +765,7 @@ def base64url( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_base64url_request( content_type=content_type, @@ -892,7 +892,7 @@ def base64url_array( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_base64url_array_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py +++ b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/aio/operations/_operations.py b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/aio/operations/_operations.py index f2b1214a3c9..8c3f8c6aaa4 100644 --- a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/aio/operations/_operations.py @@ -429,7 +429,7 @@ async def default( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_default_request( content_type=content_type, @@ -552,7 +552,7 @@ async def rfc3339( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_rfc3339_request( content_type=content_type, @@ -675,7 +675,7 @@ async def rfc7231( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_rfc7231_request( content_type=content_type, @@ -802,7 +802,7 @@ async def unix_timestamp( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_unix_timestamp_request( content_type=content_type, @@ -930,7 +930,7 @@ async def unix_timestamp_array( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_unix_timestamp_array_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/operations/_operations.py b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/operations/_operations.py index 5905c0ea544..05753b4a219 100644 --- a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/operations/_operations.py +++ b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/operations/_operations.py @@ -621,7 +621,7 @@ def default( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_default_request( content_type=content_type, @@ -744,7 +744,7 @@ def rfc3339( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_rfc3339_request( content_type=content_type, @@ -867,7 +867,7 @@ def rfc7231( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_rfc7231_request( content_type=content_type, @@ -994,7 +994,7 @@ def unix_timestamp( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_unix_timestamp_request( content_type=content_type, @@ -1122,7 +1122,7 @@ def unix_timestamp_array( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_unix_timestamp_array_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py b/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py +++ b/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/encode-duration/encode/duration/aio/operations/_operations.py b/packages/typespec-python/test/generated/encode-duration/encode/duration/aio/operations/_operations.py index 7511e3bad0c..7d03198e778 100644 --- a/packages/typespec-python/test/generated/encode-duration/encode/duration/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/encode-duration/encode/duration/aio/operations/_operations.py @@ -429,7 +429,7 @@ async def default( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_default_request( content_type=content_type, @@ -552,7 +552,7 @@ async def iso8601( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_iso8601_request( content_type=content_type, @@ -679,7 +679,7 @@ async def int32_seconds( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_int32_seconds_request( content_type=content_type, @@ -806,7 +806,7 @@ async def float_seconds( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_float_seconds_request( content_type=content_type, @@ -934,7 +934,7 @@ async def float_seconds_array( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_float_seconds_array_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/encode-duration/encode/duration/operations/_operations.py b/packages/typespec-python/test/generated/encode-duration/encode/duration/operations/_operations.py index ffa7247f1b1..27f19ec3641 100644 --- a/packages/typespec-python/test/generated/encode-duration/encode/duration/operations/_operations.py +++ b/packages/typespec-python/test/generated/encode-duration/encode/duration/operations/_operations.py @@ -617,7 +617,7 @@ def default( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_default_request( content_type=content_type, @@ -740,7 +740,7 @@ def iso8601( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_iso8601_request( content_type=content_type, @@ -867,7 +867,7 @@ def int32_seconds( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_int32_seconds_request( content_type=content_type, @@ -994,7 +994,7 @@ def float_seconds( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_float_seconds_request( content_type=content_type, @@ -1122,7 +1122,7 @@ def float_seconds_array( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_float_seconds_array_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py +++ b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_operations/_operations.py b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_operations/_operations.py index 25a41dff96d..2002fb53e39 100644 --- a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_operations/_operations.py +++ b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_operations/_operations.py @@ -215,7 +215,7 @@ def get_model(self, input: Union[_models.VisibilityModel, JSON, IO], **kwargs: A if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_get_model_request( content_type=content_type, @@ -338,7 +338,7 @@ def head_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_head_model_request( content_type=content_type, @@ -454,7 +454,7 @@ def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_put_model_request( content_type=content_type, @@ -570,7 +570,7 @@ def patch_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_patch_model_request( content_type=content_type, @@ -686,7 +686,7 @@ def post_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_post_model_request( content_type=content_type, @@ -802,7 +802,7 @@ def delete_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_delete_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/aio/_operations/_operations.py b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/aio/_operations/_operations.py index 887e784e4a7..7e7b80f6c2d 100644 --- a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/aio/_operations/_operations.py @@ -136,7 +136,7 @@ async def get_model( if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_get_model_request( content_type=content_type, @@ -259,7 +259,7 @@ async def head_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_head_model_request( content_type=content_type, @@ -375,7 +375,7 @@ async def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_put_model_request( content_type=content_type, @@ -491,7 +491,7 @@ async def patch_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_patch_model_request( content_type=content_type, @@ -607,7 +607,7 @@ async def post_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_post_model_request( content_type=content_type, @@ -723,7 +723,7 @@ async def delete_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_delete_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py +++ b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_operations/_operations.py b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_operations/_operations.py index 203c46643e1..f6a4f9366d1 100644 --- a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_operations/_operations.py +++ b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_operations/_operations.py @@ -215,7 +215,7 @@ def get_model(self, input: Union[_models.VisibilityModel, JSON, IO], **kwargs: A if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_get_model_request( content_type=content_type, @@ -332,7 +332,7 @@ def head_model(self, input: Union[_models.VisibilityModel, JSON, IO], **kwargs: if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_head_model_request( content_type=content_type, @@ -449,7 +449,7 @@ def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_put_model_request( content_type=content_type, @@ -565,7 +565,7 @@ def patch_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_patch_model_request( content_type=content_type, @@ -681,7 +681,7 @@ def post_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_post_model_request( content_type=content_type, @@ -797,7 +797,7 @@ def delete_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_delete_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/aio/_operations/_operations.py b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/aio/_operations/_operations.py index 4cea4aea0c8..d7644c42a93 100644 --- a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/aio/_operations/_operations.py @@ -136,7 +136,7 @@ async def get_model( if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_get_model_request( content_type=content_type, @@ -253,7 +253,7 @@ async def head_model(self, input: Union[_models.VisibilityModel, JSON, IO], **kw if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_head_model_request( content_type=content_type, @@ -370,7 +370,7 @@ async def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_put_model_request( content_type=content_type, @@ -486,7 +486,7 @@ async def patch_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_patch_model_request( content_type=content_type, @@ -602,7 +602,7 @@ async def post_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_post_model_request( content_type=content_type, @@ -718,7 +718,7 @@ async def delete_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_delete_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/aio/operations/_operations.py b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/aio/operations/_operations.py index 9ee5cbde8f7..2b834679a38 100644 --- a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/aio/operations/_operations.py @@ -151,7 +151,7 @@ async def set( # pylint: disable=inconsistent-return-statements _content = body else: if body is not None: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore else: _content = None @@ -270,7 +270,7 @@ async def omit( # pylint: disable=inconsistent-return-statements _content = body else: if body is not None: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore else: _content = None @@ -390,7 +390,7 @@ async def required_explicit( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_body_optionality_required_explicit_request( content_type=content_type, @@ -506,7 +506,7 @@ async def required_implicit( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_body_optionality_required_implicit_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/operations/_operations.py b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/operations/_operations.py index cebc271e1bc..b5ac3d919bb 100644 --- a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/operations/_operations.py +++ b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/operations/_operations.py @@ -205,7 +205,7 @@ def set( # pylint: disable=inconsistent-return-statements _content = body else: if body is not None: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore else: _content = None @@ -324,7 +324,7 @@ def omit( # pylint: disable=inconsistent-return-statements _content = body else: if body is not None: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore else: _content = None @@ -444,7 +444,7 @@ def required_explicit( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_body_optionality_required_explicit_request( content_type=content_type, @@ -560,7 +560,7 @@ def required_implicit( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_body_optionality_required_implicit_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py b/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/aio/operations/_operations.py b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/aio/operations/_operations.py index ce5987dcf18..7a50ba61a76 100644 --- a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/aio/operations/_operations.py @@ -150,7 +150,7 @@ async def spread_as_request_body( # pylint: disable=inconsistent-return-stateme if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_model_spread_as_request_body_request( content_type=content_type, @@ -307,7 +307,7 @@ async def spread_as_request_body( # pylint: disable=inconsistent-return-stateme if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_alias_spread_as_request_body_request( content_type=content_type, @@ -462,7 +462,7 @@ async def spread_as_request_parameter( # pylint: disable=inconsistent-return-st if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_alias_spread_as_request_parameter_request( id=id, @@ -681,7 +681,7 @@ async def spread_with_multiple_parameters( # pylint: disable=inconsistent-retur if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_alias_spread_with_multiple_parameters_request( id=id, diff --git a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/operations/_operations.py b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/operations/_operations.py index 1373b553c2d..d90f5a12170 100644 --- a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/operations/_operations.py +++ b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/operations/_operations.py @@ -218,7 +218,7 @@ def spread_as_request_body( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_model_spread_as_request_body_request( content_type=content_type, @@ -375,7 +375,7 @@ def spread_as_request_body( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_alias_spread_as_request_body_request( content_type=content_type, @@ -530,7 +530,7 @@ def spread_as_request_parameter( # pylint: disable=inconsistent-return-statemen if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_alias_spread_as_request_parameter_request( id=id, @@ -749,7 +749,7 @@ def spread_with_multiple_parameters( # pylint: disable=inconsistent-return-stat if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_alias_spread_with_multiple_parameters_request( id=id, diff --git a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py +++ b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/aio/operations/_operations.py b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/aio/operations/_operations.py index 7bcda325260..d53b2bb896a 100644 --- a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/aio/operations/_operations.py @@ -152,7 +152,7 @@ async def json( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_json_request( content_type=content_type, @@ -268,7 +268,7 @@ async def client( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_client_request( content_type=content_type, @@ -384,7 +384,7 @@ async def language( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_language_request( content_type=content_type, @@ -500,7 +500,7 @@ async def json_and_client( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_json_and_client_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/operations/_operations.py b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/operations/_operations.py index 0159cc252a7..ecc319d0641 100644 --- a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/operations/_operations.py +++ b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/operations/_operations.py @@ -223,7 +223,7 @@ def json( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_json_request( content_type=content_type, @@ -339,7 +339,7 @@ def client( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_client_request( content_type=content_type, @@ -455,7 +455,7 @@ def language( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_language_request( content_type=content_type, @@ -571,7 +571,7 @@ def json_and_client( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_property_json_and_client_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py b/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py +++ b/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py b/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py +++ b/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py b/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py +++ b/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py b/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py +++ b/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py b/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py +++ b/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py b/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py +++ b/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py b/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py +++ b/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/special-words/specialwords/aio/operations/_operations.py b/packages/typespec-python/test/generated/special-words/specialwords/aio/operations/_operations.py index 3aa880f8c3d..cfdeb0f33f0 100644 --- a/packages/typespec-python/test/generated/special-words/specialwords/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/special-words/specialwords/aio/operations/_operations.py @@ -383,7 +383,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_model_put_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/special-words/specialwords/operations/_operations.py b/packages/typespec-python/test/generated/special-words/specialwords/operations/_operations.py index edc1c77a2f1..93961bb8dfd 100644 --- a/packages/typespec-python/test/generated/special-words/specialwords/operations/_operations.py +++ b/packages/typespec-python/test/generated/special-words/specialwords/operations/_operations.py @@ -437,7 +437,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_model_put_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py b/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/typetest-array/typetest/array/aio/operations/_operations.py b/packages/typespec-python/test/generated/typetest-array/typetest/array/aio/operations/_operations.py index bd688bf52dc..42ab6cf2468 100644 --- a/packages/typespec-python/test/generated/typetest-array/typetest/array/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-array/typetest/array/aio/operations/_operations.py @@ -194,7 +194,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_int32_value_put_request( content_type=content_type, @@ -362,7 +362,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_int64_value_put_request( content_type=content_type, @@ -530,7 +530,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_boolean_value_put_request( content_type=content_type, @@ -698,7 +698,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_string_value_put_request( content_type=content_type, @@ -866,7 +866,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_float32_value_put_request( content_type=content_type, @@ -1034,7 +1034,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_datetime_value_put_request( content_type=content_type, @@ -1202,7 +1202,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_duration_value_put_request( content_type=content_type, @@ -1370,7 +1370,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_unknown_value_put_request( content_type=content_type, @@ -1538,7 +1538,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_model_value_put_request( content_type=content_type, @@ -1706,7 +1706,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_nullable_float_value_put_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-array/typetest/array/operations/_operations.py b/packages/typespec-python/test/generated/typetest-array/typetest/array/operations/_operations.py index 554b94a51f3..0811f374170 100644 --- a/packages/typespec-python/test/generated/typetest-array/typetest/array/operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-array/typetest/array/operations/_operations.py @@ -454,7 +454,7 @@ def put(self, body: Union[List[int], IO], **kwargs: Any) -> None: # pylint: dis if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_int32_value_put_request( content_type=content_type, @@ -620,7 +620,7 @@ def put(self, body: Union[List[int], IO], **kwargs: Any) -> None: # pylint: dis if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_int64_value_put_request( content_type=content_type, @@ -786,7 +786,7 @@ def put(self, body: Union[List[bool], IO], **kwargs: Any) -> None: # pylint: di if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_boolean_value_put_request( content_type=content_type, @@ -952,7 +952,7 @@ def put(self, body: Union[List[str], IO], **kwargs: Any) -> None: # pylint: dis if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_string_value_put_request( content_type=content_type, @@ -1120,7 +1120,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_float32_value_put_request( content_type=content_type, @@ -1288,7 +1288,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_datetime_value_put_request( content_type=content_type, @@ -1456,7 +1456,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_duration_value_put_request( content_type=content_type, @@ -1622,7 +1622,7 @@ def put(self, body: Union[List[Any], IO], **kwargs: Any) -> None: # pylint: dis if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_unknown_value_put_request( content_type=content_type, @@ -1790,7 +1790,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_model_value_put_request( content_type=content_type, @@ -1958,7 +1958,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_nullable_float_value_put_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/aio/operations/_operations.py b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/aio/operations/_operations.py index 8b9d2841345..237ebce312f 100644 --- a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/aio/operations/_operations.py @@ -196,7 +196,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_int32_value_put_request( content_type=content_type, @@ -364,7 +364,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_int64_value_put_request( content_type=content_type, @@ -532,7 +532,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_boolean_value_put_request( content_type=content_type, @@ -700,7 +700,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_string_value_put_request( content_type=content_type, @@ -868,7 +868,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_float32_value_put_request( content_type=content_type, @@ -1036,7 +1036,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_datetime_value_put_request( content_type=content_type, @@ -1204,7 +1204,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_duration_value_put_request( content_type=content_type, @@ -1372,7 +1372,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_unknown_value_put_request( content_type=content_type, @@ -1540,7 +1540,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_model_value_put_request( content_type=content_type, @@ -1708,7 +1708,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_recursive_model_value_put_request( content_type=content_type, @@ -1876,7 +1876,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_nullable_float_value_put_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/operations/_operations.py b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/operations/_operations.py index 7a06ab704fe..a468f6c20aa 100644 --- a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/operations/_operations.py @@ -484,7 +484,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_int32_value_put_request( content_type=content_type, @@ -652,7 +652,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_int64_value_put_request( content_type=content_type, @@ -820,7 +820,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_boolean_value_put_request( content_type=content_type, @@ -988,7 +988,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_string_value_put_request( content_type=content_type, @@ -1156,7 +1156,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_float32_value_put_request( content_type=content_type, @@ -1324,7 +1324,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_datetime_value_put_request( content_type=content_type, @@ -1492,7 +1492,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_duration_value_put_request( content_type=content_type, @@ -1660,7 +1660,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_unknown_value_put_request( content_type=content_type, @@ -1828,7 +1828,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_model_value_put_request( content_type=content_type, @@ -1996,7 +1996,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_recursive_model_value_put_request( content_type=content_type, @@ -2164,7 +2164,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_nullable_float_value_put_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_operations/_operations.py index 693f93d2acf..da51ede8123 100644 --- a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_operations/_operations.py @@ -227,7 +227,7 @@ def put_known_value( # pylint: disable=inconsistent-return-statements content_type: str = kwargs.pop("content_type", _headers.pop("Content-Type", "application/json")) cls: ClsType[None] = kwargs.pop("cls", None) - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_extensible_put_known_value_request( content_type=content_type, @@ -285,7 +285,7 @@ def put_unknown_value( # pylint: disable=inconsistent-return-statements content_type: str = kwargs.pop("content_type", _headers.pop("Content-Type", "application/json")) cls: ClsType[None] = kwargs.pop("cls", None) - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_extensible_put_unknown_value_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/aio/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/aio/_operations/_operations.py index b02faa4de53..af2f0d5a4fa 100644 --- a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/aio/_operations/_operations.py @@ -173,7 +173,7 @@ async def put_known_value( # pylint: disable=inconsistent-return-statements content_type: str = kwargs.pop("content_type", _headers.pop("Content-Type", "application/json")) cls: ClsType[None] = kwargs.pop("cls", None) - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_extensible_put_known_value_request( content_type=content_type, @@ -231,7 +231,7 @@ async def put_unknown_value( # pylint: disable=inconsistent-return-statements content_type: str = kwargs.pop("content_type", _headers.pop("Content-Type", "application/json")) cls: ClsType[None] = kwargs.pop("cls", None) - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_extensible_put_unknown_value_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_operations/_operations.py index 9c2afb65d6d..0817e152bd8 100644 --- a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_operations/_operations.py @@ -161,7 +161,7 @@ def put_known_value( # pylint: disable=inconsistent-return-statements content_type: str = kwargs.pop("content_type", _headers.pop("Content-Type", "application/json")) cls: ClsType[None] = kwargs.pop("cls", None) - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_fixed_put_known_value_request( content_type=content_type, @@ -219,7 +219,7 @@ def put_unknown_value( # pylint: disable=inconsistent-return-statements content_type: str = kwargs.pop("content_type", _headers.pop("Content-Type", "application/json")) cls: ClsType[None] = kwargs.pop("cls", None) - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_fixed_put_unknown_value_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/aio/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/aio/_operations/_operations.py index 60b0427db76..1cd18387312 100644 --- a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/aio/_operations/_operations.py @@ -120,7 +120,7 @@ async def put_known_value( # pylint: disable=inconsistent-return-statements content_type: str = kwargs.pop("content_type", _headers.pop("Content-Type", "application/json")) cls: ClsType[None] = kwargs.pop("cls", None) - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_fixed_put_known_value_request( content_type=content_type, @@ -178,7 +178,7 @@ async def put_unknown_value( # pylint: disable=inconsistent-return-statements content_type: str = kwargs.pop("content_type", _headers.pop("Content-Type", "application/json")) cls: ClsType[None] = kwargs.pop("cls", None) - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_fixed_put_unknown_value_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_operations/_operations.py index 4e05cd2efd4..40568f272ec 100644 --- a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_operations/_operations.py @@ -177,7 +177,7 @@ def put_empty( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_empty_put_empty_request( content_type=content_type, @@ -345,7 +345,7 @@ def post_round_trip_empty( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_empty_post_round_trip_empty_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/aio/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/aio/_operations/_operations.py index f9755259a1c..2992a622762 100644 --- a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/aio/_operations/_operations.py @@ -133,7 +133,7 @@ async def put_empty( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_empty_put_empty_request( content_type=content_type, @@ -301,7 +301,7 @@ async def post_round_trip_empty( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_empty_post_round_trip_empty_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_operations/_operations.py index 78874763f51..aa4fb9cbc1f 100644 --- a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_operations/_operations.py @@ -261,7 +261,7 @@ def post_valid( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_inheritance_post_valid_request( content_type=content_type, @@ -423,7 +423,7 @@ def put_valid(self, input: Union[_models.Siamese, JSON, IO], **kwargs: Any) -> _ if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_inheritance_put_valid_request( content_type=content_type, @@ -598,7 +598,7 @@ def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_inheritance_put_model_request( content_type=content_type, @@ -766,7 +766,7 @@ def put_recursive_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_inheritance_put_recursive_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/aio/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/aio/_operations/_operations.py index a55e33ecf5a..8f5f5371512 100644 --- a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/aio/_operations/_operations.py @@ -139,7 +139,7 @@ async def post_valid( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_inheritance_post_valid_request( content_type=content_type, @@ -301,7 +301,7 @@ async def put_valid(self, input: Union[_models.Siamese, JSON, IO], **kwargs: Any if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_inheritance_put_valid_request( content_type=content_type, @@ -476,7 +476,7 @@ async def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_inheritance_put_model_request( content_type=content_type, @@ -644,7 +644,7 @@ async def put_recursive_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_inheritance_put_recursive_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_operations/_operations.py index fbaffabe16b..ec63853e788 100644 --- a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_operations/_operations.py @@ -177,7 +177,7 @@ def input( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_usage_input_request( content_type=content_type, @@ -345,7 +345,7 @@ def input_and_output( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_usage_input_and_output_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/aio/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/aio/_operations/_operations.py index ba6f6d005f9..f352dde4d8e 100644 --- a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/aio/_operations/_operations.py @@ -133,7 +133,7 @@ async def input( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_usage_input_request( content_type=content_type, @@ -301,7 +301,7 @@ async def input_and_output( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_usage_input_and_output_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_operations/_operations.py index 01dfe720242..c7b3751f3ea 100644 --- a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_operations/_operations.py @@ -215,7 +215,7 @@ def get_model(self, input: Union[_models.VisibilityModel, JSON, IO], **kwargs: A if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_get_model_request( content_type=content_type, @@ -332,7 +332,7 @@ def head_model(self, input: Union[_models.VisibilityModel, JSON, IO], **kwargs: if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_head_model_request( content_type=content_type, @@ -449,7 +449,7 @@ def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_put_model_request( content_type=content_type, @@ -565,7 +565,7 @@ def patch_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_patch_model_request( content_type=content_type, @@ -681,7 +681,7 @@ def post_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_post_model_request( content_type=content_type, @@ -797,7 +797,7 @@ def delete_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_delete_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/aio/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/aio/_operations/_operations.py index dc17477ca19..632491107bb 100644 --- a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/aio/_operations/_operations.py @@ -136,7 +136,7 @@ async def get_model( if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_get_model_request( content_type=content_type, @@ -253,7 +253,7 @@ async def head_model(self, input: Union[_models.VisibilityModel, JSON, IO], **kw if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_head_model_request( content_type=content_type, @@ -370,7 +370,7 @@ async def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_put_model_request( content_type=content_type, @@ -486,7 +486,7 @@ async def patch_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_patch_model_request( content_type=content_type, @@ -602,7 +602,7 @@ async def post_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_post_model_request( content_type=content_type, @@ -718,7 +718,7 @@ async def delete_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_visibility_delete_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/aio/operations/_operations.py b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/aio/operations/_operations.py index b595ad795cd..0bb00efc2bd 100644 --- a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/aio/operations/_operations.py @@ -272,7 +272,7 @@ async def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_string_patch_non_null_request( content_type=content_type, @@ -387,7 +387,7 @@ async def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_string_patch_null_request( content_type=content_type, @@ -624,7 +624,7 @@ async def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_bytes_patch_non_null_request( content_type=content_type, @@ -739,7 +739,7 @@ async def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_bytes_patch_null_request( content_type=content_type, @@ -976,7 +976,7 @@ async def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_datetime_patch_non_null_request( content_type=content_type, @@ -1091,7 +1091,7 @@ async def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_datetime_patch_null_request( content_type=content_type, @@ -1328,7 +1328,7 @@ async def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_duration_patch_non_null_request( content_type=content_type, @@ -1443,7 +1443,7 @@ async def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_duration_patch_null_request( content_type=content_type, @@ -1684,7 +1684,7 @@ async def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_collections_byte_patch_non_null_request( content_type=content_type, @@ -1803,7 +1803,7 @@ async def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_collections_byte_patch_null_request( content_type=content_type, @@ -2046,7 +2046,7 @@ async def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_collections_model_patch_non_null_request( content_type=content_type, @@ -2165,7 +2165,7 @@ async def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_collections_model_patch_null_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/operations/_operations.py b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/operations/_operations.py index b17a4d533a5..d4d85338c19 100644 --- a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/operations/_operations.py @@ -586,7 +586,7 @@ def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_string_patch_non_null_request( content_type=content_type, @@ -701,7 +701,7 @@ def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_string_patch_null_request( content_type=content_type, @@ -938,7 +938,7 @@ def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_bytes_patch_non_null_request( content_type=content_type, @@ -1053,7 +1053,7 @@ def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_bytes_patch_null_request( content_type=content_type, @@ -1290,7 +1290,7 @@ def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_datetime_patch_non_null_request( content_type=content_type, @@ -1405,7 +1405,7 @@ def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_datetime_patch_null_request( content_type=content_type, @@ -1642,7 +1642,7 @@ def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_duration_patch_non_null_request( content_type=content_type, @@ -1757,7 +1757,7 @@ def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_duration_patch_null_request( content_type=content_type, @@ -1998,7 +1998,7 @@ def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_collections_byte_patch_non_null_request( content_type=content_type, @@ -2117,7 +2117,7 @@ def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_collections_byte_patch_null_request( content_type=content_type, @@ -2360,7 +2360,7 @@ def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_collections_model_patch_non_null_request( content_type=content_type, @@ -2479,7 +2479,7 @@ def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_collections_model_patch_null_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/aio/operations/_operations.py b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/aio/operations/_operations.py index dcb9dfb01b3..daa3f2c7730 100644 --- a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/aio/operations/_operations.py @@ -277,7 +277,7 @@ async def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_string_put_all_request( content_type=content_type, @@ -393,7 +393,7 @@ async def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_string_put_default_request( content_type=content_type, @@ -631,7 +631,7 @@ async def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_bytes_put_all_request( content_type=content_type, @@ -747,7 +747,7 @@ async def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_bytes_put_default_request( content_type=content_type, @@ -985,7 +985,7 @@ async def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_datetime_put_all_request( content_type=content_type, @@ -1101,7 +1101,7 @@ async def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_datetime_put_default_request( content_type=content_type, @@ -1339,7 +1339,7 @@ async def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_duration_put_all_request( content_type=content_type, @@ -1455,7 +1455,7 @@ async def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_duration_put_default_request( content_type=content_type, @@ -1693,7 +1693,7 @@ async def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_collections_byte_put_all_request( content_type=content_type, @@ -1809,7 +1809,7 @@ async def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_collections_byte_put_default_request( content_type=content_type, @@ -2049,7 +2049,7 @@ async def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_collections_model_put_all_request( content_type=content_type, @@ -2165,7 +2165,7 @@ async def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_collections_model_put_default_request( content_type=content_type, @@ -2405,7 +2405,7 @@ async def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_required_and_optional_put_all_request( content_type=content_type, @@ -2521,7 +2521,7 @@ async def put_required_only( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_required_and_optional_put_required_only_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/operations/_operations.py b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/operations/_operations.py index 3d341eec53b..268662779cb 100644 --- a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/operations/_operations.py @@ -643,7 +643,7 @@ def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_string_put_all_request( content_type=content_type, @@ -759,7 +759,7 @@ def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_string_put_default_request( content_type=content_type, @@ -997,7 +997,7 @@ def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_bytes_put_all_request( content_type=content_type, @@ -1113,7 +1113,7 @@ def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_bytes_put_default_request( content_type=content_type, @@ -1351,7 +1351,7 @@ def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_datetime_put_all_request( content_type=content_type, @@ -1467,7 +1467,7 @@ def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_datetime_put_default_request( content_type=content_type, @@ -1705,7 +1705,7 @@ def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_duration_put_all_request( content_type=content_type, @@ -1821,7 +1821,7 @@ def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_duration_put_default_request( content_type=content_type, @@ -2059,7 +2059,7 @@ def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_collections_byte_put_all_request( content_type=content_type, @@ -2175,7 +2175,7 @@ def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_collections_byte_put_default_request( content_type=content_type, @@ -2415,7 +2415,7 @@ def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_collections_model_put_all_request( content_type=content_type, @@ -2531,7 +2531,7 @@ def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_collections_model_put_default_request( content_type=content_type, @@ -2771,7 +2771,7 @@ def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_required_and_optional_put_all_request( content_type=content_type, @@ -2887,7 +2887,7 @@ def put_required_only( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_required_and_optional_put_required_only_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/aio/operations/_operations.py b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/aio/operations/_operations.py index 6c3db6f8be6..fe4230e198e 100644 --- a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/aio/operations/_operations.py @@ -235,7 +235,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_boolean_put_request( content_type=content_type, @@ -421,7 +421,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_string_put_request( content_type=content_type, @@ -607,7 +607,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_bytes_put_request( content_type=content_type, @@ -793,7 +793,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_int_put_request( content_type=content_type, @@ -979,7 +979,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_float_put_request( content_type=content_type, @@ -1165,7 +1165,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_datetime_put_request( content_type=content_type, @@ -1351,7 +1351,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_duration_put_request( content_type=content_type, @@ -1537,7 +1537,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_enum_put_request( content_type=content_type, @@ -1723,7 +1723,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_extensible_enum_put_request( content_type=content_type, @@ -1909,7 +1909,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_model_put_request( content_type=content_type, @@ -2096,7 +2096,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_collections_string_put_request( content_type=content_type, @@ -2282,7 +2282,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_collections_int_put_request( content_type=content_type, @@ -2469,7 +2469,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_collections_model_put_request( content_type=content_type, @@ -2656,7 +2656,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_dictionary_string_put_request( content_type=content_type, @@ -2842,7 +2842,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_never_put_request( content_type=content_type, @@ -3028,7 +3028,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_unknown_string_put_request( content_type=content_type, @@ -3214,7 +3214,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_unknown_int_put_request( content_type=content_type, @@ -3400,7 +3400,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_unknown_dict_put_request( content_type=content_type, @@ -3586,7 +3586,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_unknown_array_put_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/operations/_operations.py b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/operations/_operations.py index b98d01af050..047b5da8550 100644 --- a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/operations/_operations.py @@ -731,7 +731,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_boolean_put_request( content_type=content_type, @@ -917,7 +917,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_string_put_request( content_type=content_type, @@ -1103,7 +1103,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_bytes_put_request( content_type=content_type, @@ -1289,7 +1289,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_int_put_request( content_type=content_type, @@ -1475,7 +1475,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_float_put_request( content_type=content_type, @@ -1661,7 +1661,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_datetime_put_request( content_type=content_type, @@ -1847,7 +1847,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_duration_put_request( content_type=content_type, @@ -2033,7 +2033,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_enum_put_request( content_type=content_type, @@ -2219,7 +2219,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_extensible_enum_put_request( content_type=content_type, @@ -2405,7 +2405,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_model_put_request( content_type=content_type, @@ -2592,7 +2592,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_collections_string_put_request( content_type=content_type, @@ -2778,7 +2778,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_collections_int_put_request( content_type=content_type, @@ -2965,7 +2965,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_collections_model_put_request( content_type=content_type, @@ -3152,7 +3152,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_dictionary_string_put_request( content_type=content_type, @@ -3338,7 +3338,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_never_put_request( content_type=content_type, @@ -3524,7 +3524,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_unknown_string_put_request( content_type=content_type, @@ -3710,7 +3710,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_unknown_int_put_request( content_type=content_type, @@ -3896,7 +3896,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_unknown_dict_put_request( content_type=content_type, @@ -4082,7 +4082,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_unknown_array_put_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py b/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py index 48acb463cae..9ed3ec2619f 100644 --- a/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py @@ -128,10 +128,24 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.exclude_none = exclude_none + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + result = {k: v for k, v in o.items()} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + for k in readonly_props: + if k in result: + result.pop(k) + if self.exclude_none: + for k in list(result.keys()): + if result[k] is None or isinstance(result[k], _Null): + result.pop(k) + return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -296,10 +310,19 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update( + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) or isinstance(v, typing._GenericAlias) + } + ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -515,6 +538,34 @@ def _deserialize(cls, data): return cls(data) return mapped_cls._deserialize(data) # pylint: disable=protected-access + def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: + continue + if exclude_none and (v is None or isinstance(v, _Null)): + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + elif isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + elif isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + for dk, dv in v.items() + } + else: + return ( + v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + ) + def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements annotation: typing.Any, @@ -524,8 +575,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -552,22 +612,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +628,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module, rf) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) try: if annotation._name == "Dict": @@ -742,6 +791,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/typetest-union/typetest/union/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-union/typetest/union/_operations/_operations.py index c85aab0ec68..e0df1593140 100644 --- a/packages/typespec-python/test/generated/typetest-union/typetest/union/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-union/typetest/union/_operations/_operations.py @@ -188,7 +188,7 @@ def send_int( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_union_send_int_request( content_type=content_type, @@ -304,7 +304,7 @@ def send_int_array( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_union_send_int_array_request( content_type=content_type, @@ -420,7 +420,7 @@ def send_first_named_union_value( # pylint: disable=inconsistent-return-stateme if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_union_send_first_named_union_value_request( content_type=content_type, @@ -536,7 +536,7 @@ def send_second_named_union_value( # pylint: disable=inconsistent-return-statem if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_union_send_second_named_union_value_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-union/typetest/union/aio/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-union/typetest/union/aio/_operations/_operations.py index 3a4d3c32ed9..a720f0b51bd 100644 --- a/packages/typespec-python/test/generated/typetest-union/typetest/union/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-union/typetest/union/aio/_operations/_operations.py @@ -134,7 +134,7 @@ async def send_int( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_union_send_int_request( content_type=content_type, @@ -250,7 +250,7 @@ async def send_int_array( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_union_send_int_array_request( content_type=content_type, @@ -366,7 +366,7 @@ async def send_first_named_union_value( # pylint: disable=inconsistent-return-s if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_union_send_first_named_union_value_request( content_type=content_type, @@ -482,7 +482,7 @@ async def send_second_named_union_value( # pylint: disable=inconsistent-return- if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore request = build_union_send_second_named_union_value_request( content_type=content_type, From 175ac8e575e57cafbafcd8ad60cd810ae5019983 Mon Sep 17 00:00:00 2001 From: tadelesh Date: Fri, 28 Jul 2023 17:03:29 +0800 Subject: [PATCH 02/13] fix lint --- .../codegen/templates/model_base.py.jinja2 | 16 ++++++------- .../authentication/apikey/_model_base.py | 23 +++++-------------- .../authentication/http/custom/_model_base.py | 23 +++++-------------- .../authentication/oauth2/_model_base.py | 23 +++++-------------- .../authentication/union/_model_base.py | 23 +++++-------------- .../core/internal/_model_base.py | 23 +++++-------------- .../_specs_/azure/core/basic/_model_base.py | 23 +++++-------------- .../azure/core/lro/rpc/legacy/_model_base.py | 23 +++++-------------- .../azure/core/lro/standard/_model_base.py | 23 +++++-------------- .../_specs_/azure/core/traits/_model_base.py | 23 +++++-------------- .../encode-bytes/encode/bytes/_model_base.py | 23 +++++-------------- .../encode/datetime/_model_base.py | 23 +++++-------------- .../encode/duration/_model_base.py | 23 +++++-------------- .../headasbooleanfalse/_model_base.py | 23 +++++-------------- .../headasbooleantrue/_model_base.py | 23 +++++-------------- .../parameters/bodyoptionality/_model_base.py | 23 +++++-------------- .../collectionformat/_model_base.py | 23 +++++-------------- .../parameters/spread/_model_base.py | 23 +++++-------------- .../projection/projectedname/_model_base.py | 23 +++++-------------- .../resiliency/srv/driven1/_model_base.py | 23 +++++-------------- .../resiliency/srv/driven2/_model_base.py | 23 +++++-------------- .../server/path/multiple/_model_base.py | 23 +++++-------------- .../server/path/single/_model_base.py | 23 +++++-------------- .../clientrequestid/_model_base.py | 23 +++++-------------- .../repeatability/_model_base.py | 23 +++++-------------- .../special-words/specialwords/_model_base.py | 23 +++++-------------- .../typetest/array/_model_base.py | 23 +++++-------------- .../typetest/dictionary/_model_base.py | 23 +++++-------------- .../typetest/enum/extensible/_model_base.py | 23 +++++-------------- .../typetest/enum/fixed/_model_base.py | 23 +++++-------------- .../typetest/model/empty/_model_base.py | 23 +++++-------------- .../typetest/model/inheritance/_model_base.py | 23 +++++-------------- .../typetest/model/usage/_model_base.py | 23 +++++-------------- .../typetest/model/visibility/_model_base.py | 23 +++++-------------- .../typetest/property/nullable/_model_base.py | 23 +++++-------------- .../typetest/property/optional/_model_base.py | 23 +++++-------------- .../property/valuetypes/_model_base.py | 23 +++++-------------- .../typetest/union/_model_base.py | 23 +++++-------------- 38 files changed, 229 insertions(+), 638 deletions(-) diff --git a/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 b/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 index 587f9ee798d..ad8b3d787f1 100644 --- a/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 +++ b/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 @@ -16,7 +16,6 @@ import re import copy import typing import email -import json from datetime import datetime, date, time, timedelta, timezone from json import JSONEncoder import isodate @@ -136,7 +135,7 @@ class AzureJSONEncoder(JSONEncoder): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -314,13 +313,13 @@ def _get_model(module_name: str, model_name: str): models = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) + if isinstance(v, (type, typing._GenericAlias)) } module_end = module_name.rsplit(".", 1)[0] models.update({ k: v for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) + if isinstance(v, (type, typing._GenericAlias)) }) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -553,19 +552,18 @@ class Model(_MyMutableMapping): def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [ Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v ] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) \ - if hasattr(v, "as_dict") else v + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) \ + if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py b/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py b/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py b/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py b/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py b/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py +++ b/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py +++ b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py +++ b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py b/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py +++ b/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py +++ b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py +++ b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py b/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py +++ b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py b/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py +++ b/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py b/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py +++ b/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py b/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py +++ b/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py b/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py +++ b/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py b/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py +++ b/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py b/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py +++ b/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py b/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py +++ b/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py b/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py b/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py index 9ed3ec2619f..702a7e88469 100644 --- a/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py @@ -135,7 +135,7 @@ def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = F def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = {k: v for k, v in o.items()} + result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: @@ -310,18 +310,10 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = { - k: v - for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} module_end = module_name.rsplit(".", 1)[0] models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, type) or isinstance(v, typing._GenericAlias) - } + {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -554,17 +546,14 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None - elif isinstance(v, (list, tuple, set)): + if isinstance(v, (list, tuple, set)): return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] - elif isinstance(v, dict): + if isinstance(v, dict): return { dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for dk, dv in v.items() } - else: - return ( - v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v - ) + return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements From 960c298d17c69551db75401e2e5eb671b317bb16 Mon Sep 17 00:00:00 2001 From: tadelesh Date: Mon, 31 Jul 2023 18:18:48 +0800 Subject: [PATCH 03/13] fix discriminator issue --- .../codegen/serializers/builder_serializer.py | 2 +- .../codegen/templates/model_base.py.jinja2 | 30 +++++++++------- .../authentication/apikey/_model_base.py | 36 ++++++++++++------- .../authentication/http/custom/_model_base.py | 36 ++++++++++++------- .../authentication/oauth2/_model_base.py | 36 ++++++++++++------- .../authentication/union/_model_base.py | 36 ++++++++++++------- .../core/internal/_model_base.py | 36 ++++++++++++------- .../_specs_/azure/core/basic/_model_base.py | 36 ++++++++++++------- .../core/basic/_operations/_operations.py | 8 +++-- .../core/basic/aio/_operations/_operations.py | 8 +++-- .../azure/core/lro/rpc/legacy/_model_base.py | 36 ++++++++++++------- .../azure/core/lro/standard/_model_base.py | 36 ++++++++++++------- .../lro/standard/_operations/_operations.py | 4 ++- .../standard/aio/_operations/_operations.py | 4 ++- .../_specs_/azure/core/traits/_model_base.py | 36 ++++++++++++------- .../encode-bytes/encode/bytes/_model_base.py | 36 ++++++++++++------- .../encode/datetime/_model_base.py | 36 ++++++++++++------- .../encode/duration/_model_base.py | 36 ++++++++++++------- .../headasbooleanfalse/_model_base.py | 36 ++++++++++++------- .../_operations/_operations.py | 24 +++++++++---- .../aio/_operations/_operations.py | 24 +++++++++---- .../headasbooleantrue/_model_base.py | 36 ++++++++++++------- .../_operations/_operations.py | 24 +++++++++---- .../aio/_operations/_operations.py | 24 +++++++++---- .../parameters/bodyoptionality/_model_base.py | 36 ++++++++++++------- .../aio/operations/_operations.py | 8 +++-- .../bodyoptionality/operations/_operations.py | 8 +++-- .../collectionformat/_model_base.py | 36 ++++++++++++------- .../parameters/spread/_model_base.py | 36 ++++++++++++------- .../projection/projectedname/_model_base.py | 36 ++++++++++++------- .../resiliency/srv/driven1/_model_base.py | 36 ++++++++++++------- .../resiliency/srv/driven2/_model_base.py | 36 ++++++++++++------- .../server/path/multiple/_model_base.py | 36 ++++++++++++------- .../server/path/single/_model_base.py | 36 ++++++++++++------- .../clientrequestid/_model_base.py | 36 ++++++++++++------- .../repeatability/_model_base.py | 36 ++++++++++++------- .../special-words/specialwords/_model_base.py | 36 ++++++++++++------- .../typetest/array/_model_base.py | 36 ++++++++++++------- .../typetest/dictionary/_model_base.py | 36 ++++++++++++------- .../typetest/enum/extensible/_model_base.py | 36 ++++++++++++------- .../typetest/enum/fixed/_model_base.py | 36 ++++++++++++------- .../typetest/model/empty/_model_base.py | 36 ++++++++++++------- .../model/empty/_operations/_operations.py | 4 ++- .../empty/aio/_operations/_operations.py | 4 ++- .../typetest/model/inheritance/_model_base.py | 36 ++++++++++++------- .../inheritance/_operations/_operations.py | 16 ++++++--- .../aio/_operations/_operations.py | 16 ++++++--- .../typetest/model/usage/_model_base.py | 36 ++++++++++++------- .../model/usage/_operations/_operations.py | 4 ++- .../usage/aio/_operations/_operations.py | 4 ++- .../typetest/model/visibility/_model_base.py | 36 ++++++++++++------- .../visibility/_operations/_operations.py | 24 +++++++++---- .../visibility/aio/_operations/_operations.py | 24 +++++++++---- .../typetest/property/nullable/_model_base.py | 36 ++++++++++++------- .../typetest/property/optional/_model_base.py | 36 ++++++++++++------- .../property/valuetypes/_model_base.py | 36 ++++++++++++------- .../typetest/union/_model_base.py | 36 ++++++++++++------- .../typetest/union/_operations/_operations.py | 16 ++++++--- .../union/aio/_operations/_operations.py | 16 ++++++--- 59 files changed, 1104 insertions(+), 524 deletions(-) diff --git a/packages/autorest.python/autorest/codegen/serializers/builder_serializer.py b/packages/autorest.python/autorest/codegen/serializers/builder_serializer.py index 1008c2da5f7..5c537a83dd1 100644 --- a/packages/autorest.python/autorest/codegen/serializers/builder_serializer.py +++ b/packages/autorest.python/autorest/codegen/serializers/builder_serializer.py @@ -751,7 +751,7 @@ def _serialize_body_parameter(self, builder: OperationType) -> List[str]: elif self.code_model.options["models_mode"] == "dpg": create_body_call = ( f"_{body_kwarg_name} = json.dumps({body_param.client_name}, " - "cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore" + "cls=AzureJSONEncoder, exclude_readonly=True,\n exclude_none=False) # type: ignore" ) else: create_body_call = f"_{body_kwarg_name} = {body_param.client_name}" diff --git a/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 b/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 index ad8b3d787f1..4f7d3317d0a 100644 --- a/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 +++ b/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 @@ -313,13 +313,13 @@ def _get_model(module_name: str, model_name: str): models = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) + if isinstance(v, (type, typing._GenericAlias)) # type: ignore } module_end = module_name.rsplit(".", 1)[0] models.update({ k: v for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) + if isinstance(v, (type, typing._GenericAlias)) # type: ignore }) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -520,21 +520,24 @@ class Model(_MyMutableMapping): base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators: # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() - mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) + mapped_cls = cls.__mapping__.get( + data.get(discriminator), cls + ) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -628,16 +631,17 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -728,7 +732,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py b/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py b/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py b/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py b/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py b/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py +++ b/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_operations/_operations.py b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_operations/_operations.py index f09e364dcba..94a53d189c0 100644 --- a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_operations/_operations.py +++ b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_operations/_operations.py @@ -346,7 +346,9 @@ def create_or_update(self, id: int, resource: Union[_models.User, JSON, IO], **k if isinstance(resource, (IOBase, bytes)): _content = resource else: - _content = json.dumps(resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_basic_create_or_update_request( id=id, @@ -492,7 +494,9 @@ def create_or_replace(self, id: int, resource: Union[_models.User, JSON, IO], ** if isinstance(resource, (IOBase, bytes)): _content = resource else: - _content = json.dumps(resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_basic_create_or_replace_request( id=id, diff --git a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/aio/_operations/_operations.py b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/aio/_operations/_operations.py index c04a02bbf3b..b7dcacaacba 100644 --- a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/aio/_operations/_operations.py @@ -154,7 +154,9 @@ async def create_or_update(self, id: int, resource: Union[_models.User, JSON, IO if isinstance(resource, (IOBase, bytes)): _content = resource else: - _content = json.dumps(resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_basic_create_or_update_request( id=id, @@ -300,7 +302,9 @@ async def create_or_replace(self, id: int, resource: Union[_models.User, JSON, I if isinstance(resource, (IOBase, bytes)): _content = resource else: - _content = json.dumps(resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_basic_create_or_replace_request( id=id, diff --git a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_operations/_operations.py b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_operations/_operations.py index 1dce23b9be4..57622c762d0 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_operations/_operations.py +++ b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_operations/_operations.py @@ -140,7 +140,9 @@ def _create_or_replace_initial(self, name: str, resource: Union[_models.User, JS if isinstance(resource, (IOBase, bytes)): _content = resource else: - _content = json.dumps(resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_standard_create_or_replace_request( name=name, diff --git a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/aio/_operations/_operations.py b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/aio/_operations/_operations.py index baba57a788a..4e9c2ac3dbe 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/aio/_operations/_operations.py @@ -67,7 +67,9 @@ async def _create_or_replace_initial( if isinstance(resource, (IOBase, bytes)): _content = resource else: - _content = json.dumps(resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_standard_create_or_replace_request( name=name, diff --git a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py +++ b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py +++ b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py b/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py +++ b/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py +++ b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_operations/_operations.py b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_operations/_operations.py index 2002fb53e39..692bd2d2e0f 100644 --- a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_operations/_operations.py +++ b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_operations/_operations.py @@ -215,7 +215,9 @@ def get_model(self, input: Union[_models.VisibilityModel, JSON, IO], **kwargs: A if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_get_model_request( content_type=content_type, @@ -338,7 +340,9 @@ def head_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_head_model_request( content_type=content_type, @@ -454,7 +458,9 @@ def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_put_model_request( content_type=content_type, @@ -570,7 +576,9 @@ def patch_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_patch_model_request( content_type=content_type, @@ -686,7 +694,9 @@ def post_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_post_model_request( content_type=content_type, @@ -802,7 +812,9 @@ def delete_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_delete_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/aio/_operations/_operations.py b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/aio/_operations/_operations.py index 7e7b80f6c2d..96ae546d765 100644 --- a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/aio/_operations/_operations.py @@ -136,7 +136,9 @@ async def get_model( if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_get_model_request( content_type=content_type, @@ -259,7 +261,9 @@ async def head_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_head_model_request( content_type=content_type, @@ -375,7 +379,9 @@ async def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_put_model_request( content_type=content_type, @@ -491,7 +497,9 @@ async def patch_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_patch_model_request( content_type=content_type, @@ -607,7 +615,9 @@ async def post_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_post_model_request( content_type=content_type, @@ -723,7 +733,9 @@ async def delete_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_delete_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py +++ b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_operations/_operations.py b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_operations/_operations.py index f6a4f9366d1..b502aa01712 100644 --- a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_operations/_operations.py +++ b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_operations/_operations.py @@ -215,7 +215,9 @@ def get_model(self, input: Union[_models.VisibilityModel, JSON, IO], **kwargs: A if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_get_model_request( content_type=content_type, @@ -332,7 +334,9 @@ def head_model(self, input: Union[_models.VisibilityModel, JSON, IO], **kwargs: if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_head_model_request( content_type=content_type, @@ -449,7 +453,9 @@ def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_put_model_request( content_type=content_type, @@ -565,7 +571,9 @@ def patch_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_patch_model_request( content_type=content_type, @@ -681,7 +689,9 @@ def post_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_post_model_request( content_type=content_type, @@ -797,7 +807,9 @@ def delete_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_delete_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/aio/_operations/_operations.py b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/aio/_operations/_operations.py index d7644c42a93..742d25524e3 100644 --- a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/aio/_operations/_operations.py @@ -136,7 +136,9 @@ async def get_model( if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_get_model_request( content_type=content_type, @@ -253,7 +255,9 @@ async def head_model(self, input: Union[_models.VisibilityModel, JSON, IO], **kw if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_head_model_request( content_type=content_type, @@ -370,7 +374,9 @@ async def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_put_model_request( content_type=content_type, @@ -486,7 +492,9 @@ async def patch_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_patch_model_request( content_type=content_type, @@ -602,7 +610,9 @@ async def post_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_post_model_request( content_type=content_type, @@ -718,7 +728,9 @@ async def delete_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_delete_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/aio/operations/_operations.py b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/aio/operations/_operations.py index 2b834679a38..c96c77612b0 100644 --- a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/aio/operations/_operations.py @@ -151,7 +151,9 @@ async def set( # pylint: disable=inconsistent-return-statements _content = body else: if body is not None: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore else: _content = None @@ -270,7 +272,9 @@ async def omit( # pylint: disable=inconsistent-return-statements _content = body else: if body is not None: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore else: _content = None diff --git a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/operations/_operations.py b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/operations/_operations.py index b5ac3d919bb..83df422749b 100644 --- a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/operations/_operations.py +++ b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/operations/_operations.py @@ -205,7 +205,9 @@ def set( # pylint: disable=inconsistent-return-statements _content = body else: if body is not None: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore else: _content = None @@ -324,7 +326,9 @@ def omit( # pylint: disable=inconsistent-return-statements _content = body else: if body is not None: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore else: _content = None diff --git a/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py b/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py +++ b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py b/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py +++ b/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py b/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py +++ b/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py b/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py +++ b/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py b/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py +++ b/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py b/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py +++ b/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py b/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py +++ b/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py b/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py +++ b/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py b/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_operations/_operations.py index 40568f272ec..df1a0fe0bda 100644 --- a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_operations/_operations.py @@ -177,7 +177,9 @@ def put_empty( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_empty_put_empty_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/aio/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/aio/_operations/_operations.py index 2992a622762..b8f5b8ff8a7 100644 --- a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/aio/_operations/_operations.py @@ -133,7 +133,9 @@ async def put_empty( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_empty_put_empty_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_operations/_operations.py index aa4fb9cbc1f..dd2113b9e46 100644 --- a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_operations/_operations.py @@ -261,7 +261,9 @@ def post_valid( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_inheritance_post_valid_request( content_type=content_type, @@ -423,7 +425,9 @@ def put_valid(self, input: Union[_models.Siamese, JSON, IO], **kwargs: Any) -> _ if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_inheritance_put_valid_request( content_type=content_type, @@ -598,7 +602,9 @@ def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_inheritance_put_model_request( content_type=content_type, @@ -766,7 +772,9 @@ def put_recursive_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_inheritance_put_recursive_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/aio/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/aio/_operations/_operations.py index 8f5f5371512..b36d6567501 100644 --- a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/aio/_operations/_operations.py @@ -139,7 +139,9 @@ async def post_valid( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_inheritance_post_valid_request( content_type=content_type, @@ -301,7 +303,9 @@ async def put_valid(self, input: Union[_models.Siamese, JSON, IO], **kwargs: Any if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_inheritance_put_valid_request( content_type=content_type, @@ -476,7 +480,9 @@ async def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_inheritance_put_model_request( content_type=content_type, @@ -644,7 +650,9 @@ async def put_recursive_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_inheritance_put_recursive_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_operations/_operations.py index ec63853e788..a934fba3fd7 100644 --- a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_operations/_operations.py @@ -177,7 +177,9 @@ def input( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_usage_input_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/aio/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/aio/_operations/_operations.py index f352dde4d8e..20eb6eab2e4 100644 --- a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/aio/_operations/_operations.py @@ -133,7 +133,9 @@ async def input( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_usage_input_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_operations/_operations.py index c7b3751f3ea..34b40fe7ecb 100644 --- a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_operations/_operations.py @@ -215,7 +215,9 @@ def get_model(self, input: Union[_models.VisibilityModel, JSON, IO], **kwargs: A if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_get_model_request( content_type=content_type, @@ -332,7 +334,9 @@ def head_model(self, input: Union[_models.VisibilityModel, JSON, IO], **kwargs: if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_head_model_request( content_type=content_type, @@ -449,7 +453,9 @@ def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_put_model_request( content_type=content_type, @@ -565,7 +571,9 @@ def patch_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_patch_model_request( content_type=content_type, @@ -681,7 +689,9 @@ def post_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_post_model_request( content_type=content_type, @@ -797,7 +807,9 @@ def delete_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_delete_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/aio/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/aio/_operations/_operations.py index 632491107bb..47f684a38ca 100644 --- a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/aio/_operations/_operations.py @@ -136,7 +136,9 @@ async def get_model( if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_get_model_request( content_type=content_type, @@ -253,7 +255,9 @@ async def head_model(self, input: Union[_models.VisibilityModel, JSON, IO], **kw if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_head_model_request( content_type=content_type, @@ -370,7 +374,9 @@ async def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_put_model_request( content_type=content_type, @@ -486,7 +492,9 @@ async def patch_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_patch_model_request( content_type=content_type, @@ -602,7 +610,9 @@ async def post_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_post_model_request( content_type=content_type, @@ -718,7 +728,9 @@ async def delete_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_visibility_delete_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py b/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py index 702a7e88469..9c050dd6c5d 100644 --- a/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py @@ -310,10 +310,18 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } module_end = module_name.rsplit(".", 1)[0] models.update( - {k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, (type, typing._GenericAlias))} + { + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, (type, typing._GenericAlias)) # type: ignore + } ) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -514,21 +522,24 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: result = {} @@ -618,16 +629,17 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla pass if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: try: - return _deserialize(t, obj, module, rf) + return _deserialize(deserializer, obj) except DeserializationError: pass raise DeserializationError() - return functools.partial(_deserialize_with_union, annotation) + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -718,7 +730,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e diff --git a/packages/typespec-python/test/generated/typetest-union/typetest/union/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-union/typetest/union/_operations/_operations.py index e0df1593140..741a298b5d4 100644 --- a/packages/typespec-python/test/generated/typetest-union/typetest/union/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-union/typetest/union/_operations/_operations.py @@ -188,7 +188,9 @@ def send_int( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_union_send_int_request( content_type=content_type, @@ -304,7 +306,9 @@ def send_int_array( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_union_send_int_array_request( content_type=content_type, @@ -420,7 +424,9 @@ def send_first_named_union_value( # pylint: disable=inconsistent-return-stateme if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_union_send_first_named_union_value_request( content_type=content_type, @@ -536,7 +542,9 @@ def send_second_named_union_value( # pylint: disable=inconsistent-return-statem if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_union_send_second_named_union_value_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-union/typetest/union/aio/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-union/typetest/union/aio/_operations/_operations.py index a720f0b51bd..128d11d78d2 100644 --- a/packages/typespec-python/test/generated/typetest-union/typetest/union/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-union/typetest/union/aio/_operations/_operations.py @@ -134,7 +134,9 @@ async def send_int( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_union_send_int_request( content_type=content_type, @@ -250,7 +252,9 @@ async def send_int_array( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_union_send_int_array_request( content_type=content_type, @@ -366,7 +370,9 @@ async def send_first_named_union_value( # pylint: disable=inconsistent-return-s if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_union_send_first_named_union_value_request( content_type=content_type, @@ -482,7 +488,9 @@ async def send_second_named_union_value( # pylint: disable=inconsistent-return- if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps( + input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False + ) # type: ignore request = build_union_send_second_named_union_value_request( content_type=content_type, From a7e853307bc919d16f8982d029d1762689628a2c Mon Sep 17 00:00:00 2001 From: tadelesh Date: Tue, 1 Aug 2023 11:26:07 +0800 Subject: [PATCH 04/13] review comment --- .../autorest/codegen/templates/model_base.py.jinja2 | 6 +++--- .../authentication/apikey/_model_base.py | 6 +++--- .../authentication/http/custom/_model_base.py | 6 +++--- .../authentication/oauth2/_model_base.py | 6 +++--- .../authentication/union/_model_base.py | 6 +++--- .../azure/clientgenerator/core/internal/_model_base.py | 6 +++--- .../_specs_/azure/core/basic/_model_base.py | 6 +++--- .../_specs_/azure/core/lro/rpc/legacy/_model_base.py | 6 +++--- .../_specs_/azure/core/lro/standard/_model_base.py | 6 +++--- .../_specs_/azure/core/traits/_model_base.py | 6 +++--- .../test/generated/encode-bytes/encode/bytes/_model_base.py | 6 +++--- .../encode-datetime/encode/datetime/_model_base.py | 6 +++--- .../encode-duration/encode/duration/_model_base.py | 6 +++--- .../headasbooleanfalse/headasbooleanfalse/_model_base.py | 6 +++--- .../headasbooleantrue/headasbooleantrue/_model_base.py | 6 +++--- .../parameters/bodyoptionality/_model_base.py | 6 +++--- .../parameters/collectionformat/_model_base.py | 6 +++--- .../parameters-spread/parameters/spread/_model_base.py | 6 +++--- .../projection/projectedname/_model_base.py | 6 +++--- .../resiliency/srv/driven1/_model_base.py | 6 +++--- .../resiliency/srv/driven2/_model_base.py | 6 +++--- .../server/path/multiple/_model_base.py | 6 +++--- .../server-path-single/server/path/single/_model_base.py | 6 +++--- .../specialheaders/clientrequestid/_model_base.py | 6 +++--- .../specialheaders/repeatability/_model_base.py | 6 +++--- .../generated/special-words/specialwords/_model_base.py | 6 +++--- .../generated/typetest-array/typetest/array/_model_base.py | 6 +++--- .../typetest-dictionary/typetest/dictionary/_model_base.py | 6 +++--- .../typetest/enum/extensible/_model_base.py | 6 +++--- .../typetest-enum-fixed/typetest/enum/fixed/_model_base.py | 6 +++--- .../typetest/model/empty/_model_base.py | 6 +++--- .../typetest/model/inheritance/_model_base.py | 6 +++--- .../typetest/model/usage/_model_base.py | 6 +++--- .../typetest/model/visibility/_model_base.py | 6 +++--- .../typetest/property/nullable/_model_base.py | 6 +++--- .../typetest/property/optional/_model_base.py | 6 +++--- .../typetest/property/valuetypes/_model_base.py | 6 +++--- .../generated/typetest-union/typetest/union/_model_base.py | 6 +++--- 38 files changed, 114 insertions(+), 114 deletions(-) diff --git a/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 b/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 index 4f7d3317d0a..6142ccaa138 100644 --- a/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 +++ b/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 @@ -143,7 +143,7 @@ class AzureJSONEncoder(JSONEncoder): result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -544,9 +544,9 @@ class Model(_MyMutableMapping): if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py b/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py b/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py b/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py b/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py b/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py +++ b/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py +++ b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py +++ b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py b/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py +++ b/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py +++ b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py +++ b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py b/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py +++ b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py b/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py +++ b/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py b/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py +++ b/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py b/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py +++ b/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py b/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py +++ b/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py b/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py +++ b/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py b/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py +++ b/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py b/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py +++ b/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py b/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result diff --git a/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py b/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py index 9c050dd6c5d..c90edee1e0d 100644 --- a/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py @@ -143,7 +143,7 @@ def default(self, o): # pylint: disable=too-many-return-statements result.pop(k) if self.exclude_none: for k in list(result.keys()): - if result[k] is None or isinstance(result[k], _Null): + if result[k] is None: result.pop(k) return result if isinstance(o, (bytes, bytearray)): @@ -546,9 +546,9 @@ def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): - if exclude_readonly and k in readonly_props: + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and (v is None or isinstance(v, _Null)): + if exclude_none and v is None: continue result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) return result From 3ff044560c1eaffc036d0fe3b89775d0d4dff54e Mon Sep 17 00:00:00 2001 From: tadelesh Date: Wed, 2 Aug 2023 14:21:05 +0800 Subject: [PATCH 05/13] remove exclude_none --- .../codegen/serializers/builder_serializer.py | 2 +- .../codegen/templates/model_base.py.jinja2 | 25 ++++-------- .../authentication/apikey/_model_base.py | 27 ++++--------- .../authentication/http/custom/_model_base.py | 27 ++++--------- .../authentication/oauth2/_model_base.py | 27 ++++--------- .../authentication/union/_model_base.py | 27 ++++--------- .../core/internal/_model_base.py | 27 ++++--------- .../_specs_/azure/core/basic/_model_base.py | 27 ++++--------- .../core/basic/_operations/_operations.py | 8 +--- .../core/basic/aio/_operations/_operations.py | 8 +--- .../azure/core/lro/rpc/legacy/_model_base.py | 27 ++++--------- .../lro/rpc/legacy/_operations/_operations.py | 2 +- .../rpc/legacy/aio/_operations/_operations.py | 2 +- .../azure/core/lro/standard/_model_base.py | 27 ++++--------- .../lro/standard/_operations/_operations.py | 4 +- .../standard/aio/_operations/_operations.py | 4 +- .../_specs_/azure/core/traits/_model_base.py | 27 ++++--------- .../core/traits/_operations/_operations.py | 2 +- .../traits/aio/_operations/_operations.py | 2 +- .../encode-bytes/encode/bytes/_model_base.py | 27 ++++--------- .../bytes/aio/operations/_operations.py | 8 ++-- .../encode/bytes/operations/_operations.py | 8 ++-- .../encode/datetime/_model_base.py | 27 ++++--------- .../datetime/aio/operations/_operations.py | 10 ++--- .../encode/datetime/operations/_operations.py | 10 ++--- .../encode/duration/_model_base.py | 27 ++++--------- .../duration/aio/operations/_operations.py | 10 ++--- .../encode/duration/operations/_operations.py | 10 ++--- .../headasbooleanfalse/_model_base.py | 27 ++++--------- .../_operations/_operations.py | 24 +++--------- .../aio/_operations/_operations.py | 24 +++--------- .../headasbooleantrue/_model_base.py | 27 ++++--------- .../_operations/_operations.py | 24 +++--------- .../aio/_operations/_operations.py | 24 +++--------- .../parameters/bodyoptionality/_model_base.py | 27 ++++--------- .../aio/operations/_operations.py | 12 ++---- .../bodyoptionality/operations/_operations.py | 12 ++---- .../collectionformat/_model_base.py | 27 ++++--------- .../parameters/spread/_model_base.py | 27 ++++--------- .../spread/aio/operations/_operations.py | 8 ++-- .../spread/operations/_operations.py | 8 ++-- .../projection/projectedname/_model_base.py | 27 ++++--------- .../aio/operations/_operations.py | 8 ++-- .../projectedname/operations/_operations.py | 8 ++-- .../resiliency/srv/driven1/_model_base.py | 27 ++++--------- .../resiliency/srv/driven2/_model_base.py | 27 ++++--------- .../server/path/multiple/_model_base.py | 27 ++++--------- .../server/path/single/_model_base.py | 27 ++++--------- .../clientrequestid/_model_base.py | 27 ++++--------- .../repeatability/_model_base.py | 27 ++++--------- .../special-words/specialwords/_model_base.py | 27 ++++--------- .../aio/operations/_operations.py | 2 +- .../specialwords/operations/_operations.py | 2 +- .../typetest/array/_model_base.py | 27 ++++--------- .../array/aio/operations/_operations.py | 20 +++++----- .../typetest/array/operations/_operations.py | 20 +++++----- .../typetest/dictionary/_model_base.py | 27 ++++--------- .../dictionary/aio/operations/_operations.py | 22 +++++------ .../dictionary/operations/_operations.py | 22 +++++------ .../typetest/enum/extensible/_model_base.py | 27 ++++--------- .../extensible/_operations/_operations.py | 4 +- .../extensible/aio/_operations/_operations.py | 4 +- .../typetest/enum/fixed/_model_base.py | 27 ++++--------- .../enum/fixed/_operations/_operations.py | 4 +- .../enum/fixed/aio/_operations/_operations.py | 4 +- .../typetest/model/empty/_model_base.py | 27 ++++--------- .../model/empty/_operations/_operations.py | 6 +-- .../empty/aio/_operations/_operations.py | 6 +-- .../typetest/model/inheritance/_model_base.py | 27 ++++--------- .../inheritance/_operations/_operations.py | 16 ++------ .../aio/_operations/_operations.py | 16 ++------ .../typetest/model/usage/_model_base.py | 27 ++++--------- .../model/usage/_operations/_operations.py | 6 +-- .../usage/aio/_operations/_operations.py | 6 +-- .../typetest/model/visibility/_model_base.py | 27 ++++--------- .../visibility/_operations/_operations.py | 24 +++--------- .../visibility/aio/_operations/_operations.py | 24 +++--------- .../typetest/property/nullable/_model_base.py | 27 ++++--------- .../nullable/aio/operations/_operations.py | 24 ++++++------ .../nullable/operations/_operations.py | 24 ++++++------ .../typetest/property/optional/_model_base.py | 27 ++++--------- .../optional/aio/operations/_operations.py | 28 +++++++------- .../optional/operations/_operations.py | 28 +++++++------- .../property/valuetypes/_model_base.py | 27 ++++--------- .../valuetypes/aio/operations/_operations.py | 38 +++++++++---------- .../valuetypes/operations/_operations.py | 38 +++++++++---------- .../typetest/union/_model_base.py | 27 ++++--------- .../typetest/union/_operations/_operations.py | 16 ++------ .../union/aio/_operations/_operations.py | 16 ++------ 89 files changed, 569 insertions(+), 1117 deletions(-) diff --git a/packages/autorest.python/autorest/codegen/serializers/builder_serializer.py b/packages/autorest.python/autorest/codegen/serializers/builder_serializer.py index 5c537a83dd1..94bea9b1d3d 100644 --- a/packages/autorest.python/autorest/codegen/serializers/builder_serializer.py +++ b/packages/autorest.python/autorest/codegen/serializers/builder_serializer.py @@ -751,7 +751,7 @@ def _serialize_body_parameter(self, builder: OperationType) -> List[str]: elif self.code_model.options["models_mode"] == "dpg": create_body_call = ( f"_{body_kwarg_name} = json.dumps({body_param.client_name}, " - "cls=AzureJSONEncoder, exclude_readonly=True,\n exclude_none=False) # type: ignore" + "cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore" ) else: create_body_call = f"_{body_kwarg_name} = {body_param.client_name}" diff --git a/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 b/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 index 6142ccaa138..db82e2de8e3 100644 --- a/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 +++ b/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ class AzureJSONEncoder(JSONEncoder): if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -539,34 +533,31 @@ class Model(_MyMutableMapping): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): return [ - Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v ] if isinstance(v, dict): return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items() } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) \ - if hasattr(v, "as_dict") else v + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py b/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py b/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py b/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py b/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py b/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py +++ b/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_operations/_operations.py b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_operations/_operations.py index 94a53d189c0..2905707ebc6 100644 --- a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_operations/_operations.py +++ b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_operations/_operations.py @@ -346,9 +346,7 @@ def create_or_update(self, id: int, resource: Union[_models.User, JSON, IO], **k if isinstance(resource, (IOBase, bytes)): _content = resource else: - _content = json.dumps( - resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(resource, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_basic_create_or_update_request( id=id, @@ -494,9 +492,7 @@ def create_or_replace(self, id: int, resource: Union[_models.User, JSON, IO], ** if isinstance(resource, (IOBase, bytes)): _content = resource else: - _content = json.dumps( - resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(resource, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_basic_create_or_replace_request( id=id, diff --git a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/aio/_operations/_operations.py b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/aio/_operations/_operations.py index b7dcacaacba..19a5195a1d1 100644 --- a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/aio/_operations/_operations.py @@ -154,9 +154,7 @@ async def create_or_update(self, id: int, resource: Union[_models.User, JSON, IO if isinstance(resource, (IOBase, bytes)): _content = resource else: - _content = json.dumps( - resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(resource, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_basic_create_or_update_request( id=id, @@ -302,9 +300,7 @@ async def create_or_replace(self, id: int, resource: Union[_models.User, JSON, I if isinstance(resource, (IOBase, bytes)): _content = resource else: - _content = json.dumps( - resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(resource, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_basic_create_or_replace_request( id=id, diff --git a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_operations/_operations.py b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_operations/_operations.py index 4c6d89e1e84..ccad7b5d193 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_operations/_operations.py +++ b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_operations/_operations.py @@ -86,7 +86,7 @@ def _create_job_initial(self, body: Union[_models.JobData, JSON, IO], **kwargs: if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_legacy_create_job_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/aio/_operations/_operations.py b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/aio/_operations/_operations.py index 3a86c45d268..e6f8d81f32b 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/aio/_operations/_operations.py @@ -61,7 +61,7 @@ async def _create_job_initial(self, body: Union[_models.JobData, JSON, IO], **kw if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_legacy_create_job_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_operations/_operations.py b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_operations/_operations.py index 57622c762d0..3e09bf10eef 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_operations/_operations.py +++ b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_operations/_operations.py @@ -140,9 +140,7 @@ def _create_or_replace_initial(self, name: str, resource: Union[_models.User, JS if isinstance(resource, (IOBase, bytes)): _content = resource else: - _content = json.dumps( - resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(resource, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_standard_create_or_replace_request( name=name, diff --git a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/aio/_operations/_operations.py b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/aio/_operations/_operations.py index 4e9c2ac3dbe..04736e706ed 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/aio/_operations/_operations.py @@ -67,9 +67,7 @@ async def _create_or_replace_initial( if isinstance(resource, (IOBase, bytes)): _content = resource else: - _content = json.dumps( - resource, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(resource, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_standard_create_or_replace_request( name=name, diff --git a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_operations/_operations.py b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_operations/_operations.py index 712cffd06d3..1c6e991abd5 100644 --- a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_operations/_operations.py +++ b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_operations/_operations.py @@ -316,7 +316,7 @@ def repeatable_action( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_traits_repeatable_action_request( id=id, diff --git a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/aio/_operations/_operations.py b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/aio/_operations/_operations.py index 07bd85575ed..1c156d000d6 100644 --- a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/aio/_operations/_operations.py @@ -237,7 +237,7 @@ async def repeatable_action( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_traits_repeatable_action_request( id=id, diff --git a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py +++ b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/aio/operations/_operations.py b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/aio/operations/_operations.py index 200d96c1f3f..03d2e4587b0 100644 --- a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/aio/operations/_operations.py @@ -369,7 +369,7 @@ async def default( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_default_request( content_type=content_type, @@ -492,7 +492,7 @@ async def base64( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_base64_request( content_type=content_type, @@ -615,7 +615,7 @@ async def base64url( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_base64url_request( content_type=content_type, @@ -742,7 +742,7 @@ async def base64url_array( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_base64url_array_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/operations/_operations.py b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/operations/_operations.py index a00f41bcec6..e90bc1975ee 100644 --- a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/operations/_operations.py +++ b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/operations/_operations.py @@ -523,7 +523,7 @@ def default( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_default_request( content_type=content_type, @@ -642,7 +642,7 @@ def base64(self, body: Union[_models.Base64BytesProperty, JSON, IO], **kwargs: A if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_base64_request( content_type=content_type, @@ -765,7 +765,7 @@ def base64url( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_base64url_request( content_type=content_type, @@ -892,7 +892,7 @@ def base64url_array( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_base64url_array_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py +++ b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/aio/operations/_operations.py b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/aio/operations/_operations.py index 8c3f8c6aaa4..5818d66891b 100644 --- a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/aio/operations/_operations.py @@ -429,7 +429,7 @@ async def default( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_default_request( content_type=content_type, @@ -552,7 +552,7 @@ async def rfc3339( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_rfc3339_request( content_type=content_type, @@ -675,7 +675,7 @@ async def rfc7231( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_rfc7231_request( content_type=content_type, @@ -802,7 +802,7 @@ async def unix_timestamp( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_unix_timestamp_request( content_type=content_type, @@ -930,7 +930,7 @@ async def unix_timestamp_array( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_unix_timestamp_array_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/operations/_operations.py b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/operations/_operations.py index 05753b4a219..7380d8dd245 100644 --- a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/operations/_operations.py +++ b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/operations/_operations.py @@ -621,7 +621,7 @@ def default( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_default_request( content_type=content_type, @@ -744,7 +744,7 @@ def rfc3339( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_rfc3339_request( content_type=content_type, @@ -867,7 +867,7 @@ def rfc7231( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_rfc7231_request( content_type=content_type, @@ -994,7 +994,7 @@ def unix_timestamp( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_unix_timestamp_request( content_type=content_type, @@ -1122,7 +1122,7 @@ def unix_timestamp_array( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_unix_timestamp_array_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py b/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py +++ b/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/encode-duration/encode/duration/aio/operations/_operations.py b/packages/typespec-python/test/generated/encode-duration/encode/duration/aio/operations/_operations.py index 7d03198e778..e8516e9a674 100644 --- a/packages/typespec-python/test/generated/encode-duration/encode/duration/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/encode-duration/encode/duration/aio/operations/_operations.py @@ -429,7 +429,7 @@ async def default( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_default_request( content_type=content_type, @@ -552,7 +552,7 @@ async def iso8601( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_iso8601_request( content_type=content_type, @@ -679,7 +679,7 @@ async def int32_seconds( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_int32_seconds_request( content_type=content_type, @@ -806,7 +806,7 @@ async def float_seconds( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_float_seconds_request( content_type=content_type, @@ -934,7 +934,7 @@ async def float_seconds_array( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_float_seconds_array_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/encode-duration/encode/duration/operations/_operations.py b/packages/typespec-python/test/generated/encode-duration/encode/duration/operations/_operations.py index 27f19ec3641..09ab22dbbe4 100644 --- a/packages/typespec-python/test/generated/encode-duration/encode/duration/operations/_operations.py +++ b/packages/typespec-python/test/generated/encode-duration/encode/duration/operations/_operations.py @@ -617,7 +617,7 @@ def default( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_default_request( content_type=content_type, @@ -740,7 +740,7 @@ def iso8601( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_iso8601_request( content_type=content_type, @@ -867,7 +867,7 @@ def int32_seconds( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_int32_seconds_request( content_type=content_type, @@ -994,7 +994,7 @@ def float_seconds( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_float_seconds_request( content_type=content_type, @@ -1122,7 +1122,7 @@ def float_seconds_array( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_float_seconds_array_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py +++ b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_operations/_operations.py b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_operations/_operations.py index 692bd2d2e0f..d7e6ce11e43 100644 --- a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_operations/_operations.py +++ b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_operations/_operations.py @@ -215,9 +215,7 @@ def get_model(self, input: Union[_models.VisibilityModel, JSON, IO], **kwargs: A if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_get_model_request( content_type=content_type, @@ -340,9 +338,7 @@ def head_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_head_model_request( content_type=content_type, @@ -458,9 +454,7 @@ def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_put_model_request( content_type=content_type, @@ -576,9 +570,7 @@ def patch_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_patch_model_request( content_type=content_type, @@ -694,9 +686,7 @@ def post_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_post_model_request( content_type=content_type, @@ -812,9 +802,7 @@ def delete_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_delete_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/aio/_operations/_operations.py b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/aio/_operations/_operations.py index 96ae546d765..9ccd7fc3bc2 100644 --- a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/aio/_operations/_operations.py @@ -136,9 +136,7 @@ async def get_model( if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_get_model_request( content_type=content_type, @@ -261,9 +259,7 @@ async def head_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_head_model_request( content_type=content_type, @@ -379,9 +375,7 @@ async def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_put_model_request( content_type=content_type, @@ -497,9 +491,7 @@ async def patch_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_patch_model_request( content_type=content_type, @@ -615,9 +607,7 @@ async def post_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_post_model_request( content_type=content_type, @@ -733,9 +723,7 @@ async def delete_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_delete_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py +++ b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_operations/_operations.py b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_operations/_operations.py index b502aa01712..c2b3984522a 100644 --- a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_operations/_operations.py +++ b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_operations/_operations.py @@ -215,9 +215,7 @@ def get_model(self, input: Union[_models.VisibilityModel, JSON, IO], **kwargs: A if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_get_model_request( content_type=content_type, @@ -334,9 +332,7 @@ def head_model(self, input: Union[_models.VisibilityModel, JSON, IO], **kwargs: if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_head_model_request( content_type=content_type, @@ -453,9 +449,7 @@ def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_put_model_request( content_type=content_type, @@ -571,9 +565,7 @@ def patch_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_patch_model_request( content_type=content_type, @@ -689,9 +681,7 @@ def post_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_post_model_request( content_type=content_type, @@ -807,9 +797,7 @@ def delete_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_delete_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/aio/_operations/_operations.py b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/aio/_operations/_operations.py index 742d25524e3..9a42a9a34ab 100644 --- a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/aio/_operations/_operations.py @@ -136,9 +136,7 @@ async def get_model( if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_get_model_request( content_type=content_type, @@ -255,9 +253,7 @@ async def head_model(self, input: Union[_models.VisibilityModel, JSON, IO], **kw if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_head_model_request( content_type=content_type, @@ -374,9 +370,7 @@ async def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_put_model_request( content_type=content_type, @@ -492,9 +486,7 @@ async def patch_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_patch_model_request( content_type=content_type, @@ -610,9 +602,7 @@ async def post_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_post_model_request( content_type=content_type, @@ -728,9 +718,7 @@ async def delete_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_delete_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/aio/operations/_operations.py b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/aio/operations/_operations.py index c96c77612b0..81d8a481cba 100644 --- a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/aio/operations/_operations.py @@ -151,9 +151,7 @@ async def set( # pylint: disable=inconsistent-return-statements _content = body else: if body is not None: - _content = json.dumps( - body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore else: _content = None @@ -272,9 +270,7 @@ async def omit( # pylint: disable=inconsistent-return-statements _content = body else: if body is not None: - _content = json.dumps( - body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore else: _content = None @@ -394,7 +390,7 @@ async def required_explicit( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_body_optionality_required_explicit_request( content_type=content_type, @@ -510,7 +506,7 @@ async def required_implicit( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_body_optionality_required_implicit_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/operations/_operations.py b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/operations/_operations.py index 83df422749b..bf9a370fe1b 100644 --- a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/operations/_operations.py +++ b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/operations/_operations.py @@ -205,9 +205,7 @@ def set( # pylint: disable=inconsistent-return-statements _content = body else: if body is not None: - _content = json.dumps( - body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore else: _content = None @@ -326,9 +324,7 @@ def omit( # pylint: disable=inconsistent-return-statements _content = body else: if body is not None: - _content = json.dumps( - body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore else: _content = None @@ -448,7 +444,7 @@ def required_explicit( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_body_optionality_required_explicit_request( content_type=content_type, @@ -564,7 +560,7 @@ def required_implicit( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_body_optionality_required_implicit_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py b/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/aio/operations/_operations.py b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/aio/operations/_operations.py index 7a50ba61a76..439586aaaa0 100644 --- a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/aio/operations/_operations.py @@ -150,7 +150,7 @@ async def spread_as_request_body( # pylint: disable=inconsistent-return-stateme if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_model_spread_as_request_body_request( content_type=content_type, @@ -307,7 +307,7 @@ async def spread_as_request_body( # pylint: disable=inconsistent-return-stateme if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_alias_spread_as_request_body_request( content_type=content_type, @@ -462,7 +462,7 @@ async def spread_as_request_parameter( # pylint: disable=inconsistent-return-st if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_alias_spread_as_request_parameter_request( id=id, @@ -681,7 +681,7 @@ async def spread_with_multiple_parameters( # pylint: disable=inconsistent-retur if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_alias_spread_with_multiple_parameters_request( id=id, diff --git a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/operations/_operations.py b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/operations/_operations.py index d90f5a12170..7b59c17d96d 100644 --- a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/operations/_operations.py +++ b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/operations/_operations.py @@ -218,7 +218,7 @@ def spread_as_request_body( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_model_spread_as_request_body_request( content_type=content_type, @@ -375,7 +375,7 @@ def spread_as_request_body( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_alias_spread_as_request_body_request( content_type=content_type, @@ -530,7 +530,7 @@ def spread_as_request_parameter( # pylint: disable=inconsistent-return-statemen if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_alias_spread_as_request_parameter_request( id=id, @@ -749,7 +749,7 @@ def spread_with_multiple_parameters( # pylint: disable=inconsistent-return-stat if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_alias_spread_with_multiple_parameters_request( id=id, diff --git a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py +++ b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/aio/operations/_operations.py b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/aio/operations/_operations.py index d53b2bb896a..6e38a2da353 100644 --- a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/aio/operations/_operations.py @@ -152,7 +152,7 @@ async def json( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_json_request( content_type=content_type, @@ -268,7 +268,7 @@ async def client( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_client_request( content_type=content_type, @@ -384,7 +384,7 @@ async def language( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_language_request( content_type=content_type, @@ -500,7 +500,7 @@ async def json_and_client( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_json_and_client_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/operations/_operations.py b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/operations/_operations.py index ecc319d0641..53c6648f6c6 100644 --- a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/operations/_operations.py +++ b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/operations/_operations.py @@ -223,7 +223,7 @@ def json( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_json_request( content_type=content_type, @@ -339,7 +339,7 @@ def client( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_client_request( content_type=content_type, @@ -455,7 +455,7 @@ def language( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_language_request( content_type=content_type, @@ -571,7 +571,7 @@ def json_and_client( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_property_json_and_client_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py b/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py +++ b/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py b/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py +++ b/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py b/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py +++ b/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py b/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py +++ b/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py b/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py +++ b/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py b/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py +++ b/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py b/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py +++ b/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/special-words/specialwords/aio/operations/_operations.py b/packages/typespec-python/test/generated/special-words/specialwords/aio/operations/_operations.py index cfdeb0f33f0..3276e3cfcc6 100644 --- a/packages/typespec-python/test/generated/special-words/specialwords/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/special-words/specialwords/aio/operations/_operations.py @@ -383,7 +383,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_model_put_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/special-words/specialwords/operations/_operations.py b/packages/typespec-python/test/generated/special-words/specialwords/operations/_operations.py index 93961bb8dfd..549e3465d76 100644 --- a/packages/typespec-python/test/generated/special-words/specialwords/operations/_operations.py +++ b/packages/typespec-python/test/generated/special-words/specialwords/operations/_operations.py @@ -437,7 +437,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_model_put_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py b/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-array/typetest/array/aio/operations/_operations.py b/packages/typespec-python/test/generated/typetest-array/typetest/array/aio/operations/_operations.py index 42ab6cf2468..861fc928a28 100644 --- a/packages/typespec-python/test/generated/typetest-array/typetest/array/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-array/typetest/array/aio/operations/_operations.py @@ -194,7 +194,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_int32_value_put_request( content_type=content_type, @@ -362,7 +362,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_int64_value_put_request( content_type=content_type, @@ -530,7 +530,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_boolean_value_put_request( content_type=content_type, @@ -698,7 +698,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_string_value_put_request( content_type=content_type, @@ -866,7 +866,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_float32_value_put_request( content_type=content_type, @@ -1034,7 +1034,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_datetime_value_put_request( content_type=content_type, @@ -1202,7 +1202,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_duration_value_put_request( content_type=content_type, @@ -1370,7 +1370,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_unknown_value_put_request( content_type=content_type, @@ -1538,7 +1538,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_model_value_put_request( content_type=content_type, @@ -1706,7 +1706,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_nullable_float_value_put_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-array/typetest/array/operations/_operations.py b/packages/typespec-python/test/generated/typetest-array/typetest/array/operations/_operations.py index 0811f374170..776b2b6a829 100644 --- a/packages/typespec-python/test/generated/typetest-array/typetest/array/operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-array/typetest/array/operations/_operations.py @@ -454,7 +454,7 @@ def put(self, body: Union[List[int], IO], **kwargs: Any) -> None: # pylint: dis if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_int32_value_put_request( content_type=content_type, @@ -620,7 +620,7 @@ def put(self, body: Union[List[int], IO], **kwargs: Any) -> None: # pylint: dis if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_int64_value_put_request( content_type=content_type, @@ -786,7 +786,7 @@ def put(self, body: Union[List[bool], IO], **kwargs: Any) -> None: # pylint: di if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_boolean_value_put_request( content_type=content_type, @@ -952,7 +952,7 @@ def put(self, body: Union[List[str], IO], **kwargs: Any) -> None: # pylint: dis if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_string_value_put_request( content_type=content_type, @@ -1120,7 +1120,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_float32_value_put_request( content_type=content_type, @@ -1288,7 +1288,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_datetime_value_put_request( content_type=content_type, @@ -1456,7 +1456,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_duration_value_put_request( content_type=content_type, @@ -1622,7 +1622,7 @@ def put(self, body: Union[List[Any], IO], **kwargs: Any) -> None: # pylint: dis if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_unknown_value_put_request( content_type=content_type, @@ -1790,7 +1790,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_model_value_put_request( content_type=content_type, @@ -1958,7 +1958,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_nullable_float_value_put_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/aio/operations/_operations.py b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/aio/operations/_operations.py index 237ebce312f..33ff6d9d4a3 100644 --- a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/aio/operations/_operations.py @@ -196,7 +196,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_int32_value_put_request( content_type=content_type, @@ -364,7 +364,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_int64_value_put_request( content_type=content_type, @@ -532,7 +532,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_boolean_value_put_request( content_type=content_type, @@ -700,7 +700,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_string_value_put_request( content_type=content_type, @@ -868,7 +868,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_float32_value_put_request( content_type=content_type, @@ -1036,7 +1036,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_datetime_value_put_request( content_type=content_type, @@ -1204,7 +1204,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_duration_value_put_request( content_type=content_type, @@ -1372,7 +1372,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_unknown_value_put_request( content_type=content_type, @@ -1540,7 +1540,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_model_value_put_request( content_type=content_type, @@ -1708,7 +1708,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_recursive_model_value_put_request( content_type=content_type, @@ -1876,7 +1876,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_nullable_float_value_put_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/operations/_operations.py b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/operations/_operations.py index a468f6c20aa..b9dd4e5c0f2 100644 --- a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/operations/_operations.py @@ -484,7 +484,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_int32_value_put_request( content_type=content_type, @@ -652,7 +652,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_int64_value_put_request( content_type=content_type, @@ -820,7 +820,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_boolean_value_put_request( content_type=content_type, @@ -988,7 +988,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_string_value_put_request( content_type=content_type, @@ -1156,7 +1156,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_float32_value_put_request( content_type=content_type, @@ -1324,7 +1324,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_datetime_value_put_request( content_type=content_type, @@ -1492,7 +1492,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_duration_value_put_request( content_type=content_type, @@ -1660,7 +1660,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_unknown_value_put_request( content_type=content_type, @@ -1828,7 +1828,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_model_value_put_request( content_type=content_type, @@ -1996,7 +1996,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_recursive_model_value_put_request( content_type=content_type, @@ -2164,7 +2164,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_nullable_float_value_put_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_operations/_operations.py index da51ede8123..b9f30d843f6 100644 --- a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_operations/_operations.py @@ -227,7 +227,7 @@ def put_known_value( # pylint: disable=inconsistent-return-statements content_type: str = kwargs.pop("content_type", _headers.pop("Content-Type", "application/json")) cls: ClsType[None] = kwargs.pop("cls", None) - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_extensible_put_known_value_request( content_type=content_type, @@ -285,7 +285,7 @@ def put_unknown_value( # pylint: disable=inconsistent-return-statements content_type: str = kwargs.pop("content_type", _headers.pop("Content-Type", "application/json")) cls: ClsType[None] = kwargs.pop("cls", None) - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_extensible_put_unknown_value_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/aio/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/aio/_operations/_operations.py index af2f0d5a4fa..433c66a542d 100644 --- a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/aio/_operations/_operations.py @@ -173,7 +173,7 @@ async def put_known_value( # pylint: disable=inconsistent-return-statements content_type: str = kwargs.pop("content_type", _headers.pop("Content-Type", "application/json")) cls: ClsType[None] = kwargs.pop("cls", None) - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_extensible_put_known_value_request( content_type=content_type, @@ -231,7 +231,7 @@ async def put_unknown_value( # pylint: disable=inconsistent-return-statements content_type: str = kwargs.pop("content_type", _headers.pop("Content-Type", "application/json")) cls: ClsType[None] = kwargs.pop("cls", None) - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_extensible_put_unknown_value_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_operations/_operations.py index 0817e152bd8..8513b4be06e 100644 --- a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_operations/_operations.py @@ -161,7 +161,7 @@ def put_known_value( # pylint: disable=inconsistent-return-statements content_type: str = kwargs.pop("content_type", _headers.pop("Content-Type", "application/json")) cls: ClsType[None] = kwargs.pop("cls", None) - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_fixed_put_known_value_request( content_type=content_type, @@ -219,7 +219,7 @@ def put_unknown_value( # pylint: disable=inconsistent-return-statements content_type: str = kwargs.pop("content_type", _headers.pop("Content-Type", "application/json")) cls: ClsType[None] = kwargs.pop("cls", None) - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_fixed_put_unknown_value_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/aio/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/aio/_operations/_operations.py index 1cd18387312..465010b0954 100644 --- a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/aio/_operations/_operations.py @@ -120,7 +120,7 @@ async def put_known_value( # pylint: disable=inconsistent-return-statements content_type: str = kwargs.pop("content_type", _headers.pop("Content-Type", "application/json")) cls: ClsType[None] = kwargs.pop("cls", None) - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_fixed_put_known_value_request( content_type=content_type, @@ -178,7 +178,7 @@ async def put_unknown_value( # pylint: disable=inconsistent-return-statements content_type: str = kwargs.pop("content_type", _headers.pop("Content-Type", "application/json")) cls: ClsType[None] = kwargs.pop("cls", None) - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_fixed_put_unknown_value_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_operations/_operations.py index df1a0fe0bda..321c325a8ba 100644 --- a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_operations/_operations.py @@ -177,9 +177,7 @@ def put_empty( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_empty_put_empty_request( content_type=content_type, @@ -347,7 +345,7 @@ def post_round_trip_empty( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_empty_post_round_trip_empty_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/aio/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/aio/_operations/_operations.py index b8f5b8ff8a7..59fcc2e2b6b 100644 --- a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/aio/_operations/_operations.py @@ -133,9 +133,7 @@ async def put_empty( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_empty_put_empty_request( content_type=content_type, @@ -303,7 +301,7 @@ async def post_round_trip_empty( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_empty_post_round_trip_empty_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_operations/_operations.py index dd2113b9e46..9788594ecc0 100644 --- a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_operations/_operations.py @@ -261,9 +261,7 @@ def post_valid( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_inheritance_post_valid_request( content_type=content_type, @@ -425,9 +423,7 @@ def put_valid(self, input: Union[_models.Siamese, JSON, IO], **kwargs: Any) -> _ if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_inheritance_put_valid_request( content_type=content_type, @@ -602,9 +598,7 @@ def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_inheritance_put_model_request( content_type=content_type, @@ -772,9 +766,7 @@ def put_recursive_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_inheritance_put_recursive_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/aio/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/aio/_operations/_operations.py index b36d6567501..26c77e78520 100644 --- a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/aio/_operations/_operations.py @@ -139,9 +139,7 @@ async def post_valid( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_inheritance_post_valid_request( content_type=content_type, @@ -303,9 +301,7 @@ async def put_valid(self, input: Union[_models.Siamese, JSON, IO], **kwargs: Any if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_inheritance_put_valid_request( content_type=content_type, @@ -480,9 +476,7 @@ async def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_inheritance_put_model_request( content_type=content_type, @@ -650,9 +644,7 @@ async def put_recursive_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_inheritance_put_recursive_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_operations/_operations.py index a934fba3fd7..68dfcb15045 100644 --- a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_operations/_operations.py @@ -177,9 +177,7 @@ def input( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_usage_input_request( content_type=content_type, @@ -347,7 +345,7 @@ def input_and_output( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_usage_input_and_output_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/aio/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/aio/_operations/_operations.py index 20eb6eab2e4..35b3ad6f89c 100644 --- a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/aio/_operations/_operations.py @@ -133,9 +133,7 @@ async def input( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_usage_input_request( content_type=content_type, @@ -303,7 +301,7 @@ async def input_and_output( if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_usage_input_and_output_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_operations/_operations.py index 34b40fe7ecb..7cf8c45d865 100644 --- a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_operations/_operations.py @@ -215,9 +215,7 @@ def get_model(self, input: Union[_models.VisibilityModel, JSON, IO], **kwargs: A if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_get_model_request( content_type=content_type, @@ -334,9 +332,7 @@ def head_model(self, input: Union[_models.VisibilityModel, JSON, IO], **kwargs: if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_head_model_request( content_type=content_type, @@ -453,9 +449,7 @@ def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_put_model_request( content_type=content_type, @@ -571,9 +565,7 @@ def patch_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_patch_model_request( content_type=content_type, @@ -689,9 +681,7 @@ def post_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_post_model_request( content_type=content_type, @@ -807,9 +797,7 @@ def delete_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_delete_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/aio/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/aio/_operations/_operations.py index 47f684a38ca..8d503633c40 100644 --- a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/aio/_operations/_operations.py @@ -136,9 +136,7 @@ async def get_model( if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_get_model_request( content_type=content_type, @@ -255,9 +253,7 @@ async def head_model(self, input: Union[_models.VisibilityModel, JSON, IO], **kw if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_head_model_request( content_type=content_type, @@ -374,9 +370,7 @@ async def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_put_model_request( content_type=content_type, @@ -492,9 +486,7 @@ async def patch_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_patch_model_request( content_type=content_type, @@ -610,9 +602,7 @@ async def post_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_post_model_request( content_type=content_type, @@ -728,9 +718,7 @@ async def delete_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_visibility_delete_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/aio/operations/_operations.py b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/aio/operations/_operations.py index 0bb00efc2bd..b526ea2db5a 100644 --- a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/aio/operations/_operations.py @@ -272,7 +272,7 @@ async def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_string_patch_non_null_request( content_type=content_type, @@ -387,7 +387,7 @@ async def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_string_patch_null_request( content_type=content_type, @@ -624,7 +624,7 @@ async def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_bytes_patch_non_null_request( content_type=content_type, @@ -739,7 +739,7 @@ async def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_bytes_patch_null_request( content_type=content_type, @@ -976,7 +976,7 @@ async def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_datetime_patch_non_null_request( content_type=content_type, @@ -1091,7 +1091,7 @@ async def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_datetime_patch_null_request( content_type=content_type, @@ -1328,7 +1328,7 @@ async def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_duration_patch_non_null_request( content_type=content_type, @@ -1443,7 +1443,7 @@ async def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_duration_patch_null_request( content_type=content_type, @@ -1684,7 +1684,7 @@ async def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_collections_byte_patch_non_null_request( content_type=content_type, @@ -1803,7 +1803,7 @@ async def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_collections_byte_patch_null_request( content_type=content_type, @@ -2046,7 +2046,7 @@ async def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_collections_model_patch_non_null_request( content_type=content_type, @@ -2165,7 +2165,7 @@ async def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_collections_model_patch_null_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/operations/_operations.py b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/operations/_operations.py index d4d85338c19..aa455a264b5 100644 --- a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/operations/_operations.py @@ -586,7 +586,7 @@ def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_string_patch_non_null_request( content_type=content_type, @@ -701,7 +701,7 @@ def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_string_patch_null_request( content_type=content_type, @@ -938,7 +938,7 @@ def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_bytes_patch_non_null_request( content_type=content_type, @@ -1053,7 +1053,7 @@ def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_bytes_patch_null_request( content_type=content_type, @@ -1290,7 +1290,7 @@ def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_datetime_patch_non_null_request( content_type=content_type, @@ -1405,7 +1405,7 @@ def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_datetime_patch_null_request( content_type=content_type, @@ -1642,7 +1642,7 @@ def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_duration_patch_non_null_request( content_type=content_type, @@ -1757,7 +1757,7 @@ def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_duration_patch_null_request( content_type=content_type, @@ -1998,7 +1998,7 @@ def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_collections_byte_patch_non_null_request( content_type=content_type, @@ -2117,7 +2117,7 @@ def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_collections_byte_patch_null_request( content_type=content_type, @@ -2360,7 +2360,7 @@ def patch_non_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_collections_model_patch_non_null_request( content_type=content_type, @@ -2479,7 +2479,7 @@ def patch_null( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_collections_model_patch_null_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/aio/operations/_operations.py b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/aio/operations/_operations.py index daa3f2c7730..b7d7c006a4c 100644 --- a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/aio/operations/_operations.py @@ -277,7 +277,7 @@ async def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_string_put_all_request( content_type=content_type, @@ -393,7 +393,7 @@ async def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_string_put_default_request( content_type=content_type, @@ -631,7 +631,7 @@ async def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_bytes_put_all_request( content_type=content_type, @@ -747,7 +747,7 @@ async def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_bytes_put_default_request( content_type=content_type, @@ -985,7 +985,7 @@ async def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_datetime_put_all_request( content_type=content_type, @@ -1101,7 +1101,7 @@ async def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_datetime_put_default_request( content_type=content_type, @@ -1339,7 +1339,7 @@ async def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_duration_put_all_request( content_type=content_type, @@ -1455,7 +1455,7 @@ async def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_duration_put_default_request( content_type=content_type, @@ -1693,7 +1693,7 @@ async def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_collections_byte_put_all_request( content_type=content_type, @@ -1809,7 +1809,7 @@ async def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_collections_byte_put_default_request( content_type=content_type, @@ -2049,7 +2049,7 @@ async def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_collections_model_put_all_request( content_type=content_type, @@ -2165,7 +2165,7 @@ async def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_collections_model_put_default_request( content_type=content_type, @@ -2405,7 +2405,7 @@ async def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_required_and_optional_put_all_request( content_type=content_type, @@ -2521,7 +2521,7 @@ async def put_required_only( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_required_and_optional_put_required_only_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/operations/_operations.py b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/operations/_operations.py index 268662779cb..7dfbbc73eb1 100644 --- a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/operations/_operations.py @@ -643,7 +643,7 @@ def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_string_put_all_request( content_type=content_type, @@ -759,7 +759,7 @@ def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_string_put_default_request( content_type=content_type, @@ -997,7 +997,7 @@ def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_bytes_put_all_request( content_type=content_type, @@ -1113,7 +1113,7 @@ def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_bytes_put_default_request( content_type=content_type, @@ -1351,7 +1351,7 @@ def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_datetime_put_all_request( content_type=content_type, @@ -1467,7 +1467,7 @@ def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_datetime_put_default_request( content_type=content_type, @@ -1705,7 +1705,7 @@ def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_duration_put_all_request( content_type=content_type, @@ -1821,7 +1821,7 @@ def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_duration_put_default_request( content_type=content_type, @@ -2059,7 +2059,7 @@ def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_collections_byte_put_all_request( content_type=content_type, @@ -2175,7 +2175,7 @@ def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_collections_byte_put_default_request( content_type=content_type, @@ -2415,7 +2415,7 @@ def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_collections_model_put_all_request( content_type=content_type, @@ -2531,7 +2531,7 @@ def put_default( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_collections_model_put_default_request( content_type=content_type, @@ -2771,7 +2771,7 @@ def put_all( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_required_and_optional_put_all_request( content_type=content_type, @@ -2887,7 +2887,7 @@ def put_required_only( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_required_and_optional_put_required_only_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/aio/operations/_operations.py b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/aio/operations/_operations.py index fe4230e198e..141c8da366c 100644 --- a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/aio/operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/aio/operations/_operations.py @@ -235,7 +235,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_boolean_put_request( content_type=content_type, @@ -421,7 +421,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_string_put_request( content_type=content_type, @@ -607,7 +607,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_bytes_put_request( content_type=content_type, @@ -793,7 +793,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_int_put_request( content_type=content_type, @@ -979,7 +979,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_float_put_request( content_type=content_type, @@ -1165,7 +1165,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_datetime_put_request( content_type=content_type, @@ -1351,7 +1351,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_duration_put_request( content_type=content_type, @@ -1537,7 +1537,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_enum_put_request( content_type=content_type, @@ -1723,7 +1723,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_extensible_enum_put_request( content_type=content_type, @@ -1909,7 +1909,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_model_put_request( content_type=content_type, @@ -2096,7 +2096,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_collections_string_put_request( content_type=content_type, @@ -2282,7 +2282,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_collections_int_put_request( content_type=content_type, @@ -2469,7 +2469,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_collections_model_put_request( content_type=content_type, @@ -2656,7 +2656,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_dictionary_string_put_request( content_type=content_type, @@ -2842,7 +2842,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_never_put_request( content_type=content_type, @@ -3028,7 +3028,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_unknown_string_put_request( content_type=content_type, @@ -3214,7 +3214,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_unknown_int_put_request( content_type=content_type, @@ -3400,7 +3400,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_unknown_dict_put_request( content_type=content_type, @@ -3586,7 +3586,7 @@ async def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_unknown_array_put_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/operations/_operations.py b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/operations/_operations.py index 047b5da8550..94164fc701d 100644 --- a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/operations/_operations.py @@ -731,7 +731,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_boolean_put_request( content_type=content_type, @@ -917,7 +917,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_string_put_request( content_type=content_type, @@ -1103,7 +1103,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_bytes_put_request( content_type=content_type, @@ -1289,7 +1289,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_int_put_request( content_type=content_type, @@ -1475,7 +1475,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_float_put_request( content_type=content_type, @@ -1661,7 +1661,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_datetime_put_request( content_type=content_type, @@ -1847,7 +1847,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_duration_put_request( content_type=content_type, @@ -2033,7 +2033,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_enum_put_request( content_type=content_type, @@ -2219,7 +2219,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_extensible_enum_put_request( content_type=content_type, @@ -2405,7 +2405,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_model_put_request( content_type=content_type, @@ -2592,7 +2592,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_collections_string_put_request( content_type=content_type, @@ -2778,7 +2778,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_collections_int_put_request( content_type=content_type, @@ -2965,7 +2965,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_collections_model_put_request( content_type=content_type, @@ -3152,7 +3152,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_dictionary_string_put_request( content_type=content_type, @@ -3338,7 +3338,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_never_put_request( content_type=content_type, @@ -3524,7 +3524,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_unknown_string_put_request( content_type=content_type, @@ -3710,7 +3710,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_unknown_int_put_request( content_type=content_type, @@ -3896,7 +3896,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_unknown_dict_put_request( content_type=content_type, @@ -4082,7 +4082,7 @@ def put( # pylint: disable=inconsistent-return-statements if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_unknown_array_put_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py b/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py index c90edee1e0d..05a6c6f41a4 100644 --- a/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py @@ -128,10 +128,9 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" - def __init__(self, *args, exclude_readonly: bool = False, exclude_none: bool = False, **kwargs): + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): super().__init__(*args, **kwargs) self.exclude_readonly = exclude_readonly - self.exclude_none = exclude_none def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): @@ -139,12 +138,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] for k in readonly_props: - if k in result: - result.pop(k) - if self.exclude_none: - for k in list(result.keys()): - if result[k] is None: - result.pop(k) + result.pop(k, None) return result if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() @@ -541,30 +535,25 @@ def _deserialize(cls, data, exist_discriminators): return cls(data) return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access - def as_dict(self, *, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] for k, v in self.items(): if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false continue - if exclude_none and v is None: - continue - result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly, exclude_none=exclude_none) + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) return result @staticmethod - def _as_dict_value(v: typing.Any, exclude_readonly: bool = False, exclude_none: bool = False) -> typing.Any: + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: if v is None or isinstance(v, _Null): return None if isinstance(v, (list, tuple, set)): - return [Model._as_dict_value(x, exclude_readonly=exclude_readonly, exclude_none=exclude_none) for x in v] + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] if isinstance(v, dict): - return { - dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly, exclude_none=exclude_none) - for dk, dv in v.items() - } - return v.as_dict(exclude_readonly=exclude_readonly, exclude_none=exclude_none) if hasattr(v, "as_dict") else v + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements diff --git a/packages/typespec-python/test/generated/typetest-union/typetest/union/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-union/typetest/union/_operations/_operations.py index 741a298b5d4..7055e70a491 100644 --- a/packages/typespec-python/test/generated/typetest-union/typetest/union/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-union/typetest/union/_operations/_operations.py @@ -188,9 +188,7 @@ def send_int( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_union_send_int_request( content_type=content_type, @@ -306,9 +304,7 @@ def send_int_array( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_union_send_int_array_request( content_type=content_type, @@ -424,9 +420,7 @@ def send_first_named_union_value( # pylint: disable=inconsistent-return-stateme if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_union_send_first_named_union_value_request( content_type=content_type, @@ -542,9 +536,7 @@ def send_second_named_union_value( # pylint: disable=inconsistent-return-statem if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_union_send_second_named_union_value_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-union/typetest/union/aio/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-union/typetest/union/aio/_operations/_operations.py index 128d11d78d2..d758589f218 100644 --- a/packages/typespec-python/test/generated/typetest-union/typetest/union/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-union/typetest/union/aio/_operations/_operations.py @@ -134,9 +134,7 @@ async def send_int( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_union_send_int_request( content_type=content_type, @@ -252,9 +250,7 @@ async def send_int_array( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_union_send_int_array_request( content_type=content_type, @@ -370,9 +366,7 @@ async def send_first_named_union_value( # pylint: disable=inconsistent-return-s if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_union_send_first_named_union_value_request( content_type=content_type, @@ -488,9 +482,7 @@ async def send_second_named_union_value( # pylint: disable=inconsistent-return- if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps( - input, cls=AzureJSONEncoder, exclude_readonly=True, exclude_none=False - ) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_union_send_second_named_union_value_request( content_type=content_type, From 4c892199a19b808d59910a71587afd548001f87b Mon Sep 17 00:00:00 2001 From: tadelesh Date: Wed, 2 Aug 2023 14:54:08 +0800 Subject: [PATCH 06/13] add as_dict doc --- .../autorest/codegen/templates/model_base.py.jinja2 | 7 +++++++ .../authentication/apikey/_model_base.py | 7 +++++++ .../authentication/http/custom/_model_base.py | 7 +++++++ .../authentication/oauth2/_model_base.py | 7 +++++++ .../authentication/union/_model_base.py | 7 +++++++ .../azure/clientgenerator/core/internal/_model_base.py | 7 +++++++ .../_specs_/azure/core/basic/_model_base.py | 7 +++++++ .../_specs_/azure/core/lro/rpc/legacy/_model_base.py | 7 +++++++ .../_specs_/azure/core/lro/standard/_model_base.py | 7 +++++++ .../_specs_/azure/core/traits/_model_base.py | 7 +++++++ .../generated/encode-bytes/encode/bytes/_model_base.py | 7 +++++++ .../encode-datetime/encode/datetime/_model_base.py | 7 +++++++ .../encode-duration/encode/duration/_model_base.py | 7 +++++++ .../headasbooleanfalse/headasbooleanfalse/_model_base.py | 7 +++++++ .../headasbooleantrue/headasbooleantrue/_model_base.py | 7 +++++++ .../parameters/bodyoptionality/_model_base.py | 7 +++++++ .../parameters/collectionformat/_model_base.py | 7 +++++++ .../parameters-spread/parameters/spread/_model_base.py | 7 +++++++ .../projection/projectedname/_model_base.py | 7 +++++++ .../resiliency/srv/driven1/_model_base.py | 7 +++++++ .../resiliency/srv/driven2/_model_base.py | 7 +++++++ .../server/path/multiple/_model_base.py | 7 +++++++ .../server-path-single/server/path/single/_model_base.py | 7 +++++++ .../specialheaders/clientrequestid/_model_base.py | 7 +++++++ .../specialheaders/repeatability/_model_base.py | 7 +++++++ .../generated/special-words/specialwords/_model_base.py | 7 +++++++ .../generated/typetest-array/typetest/array/_model_base.py | 7 +++++++ .../typetest-dictionary/typetest/dictionary/_model_base.py | 7 +++++++ .../typetest/enum/extensible/_model_base.py | 7 +++++++ .../typetest-enum-fixed/typetest/enum/fixed/_model_base.py | 7 +++++++ .../typetest/model/empty/_model_base.py | 7 +++++++ .../typetest/model/inheritance/_model_base.py | 7 +++++++ .../typetest/model/usage/_model_base.py | 7 +++++++ .../typetest/model/visibility/_model_base.py | 7 +++++++ .../typetest/property/nullable/_model_base.py | 7 +++++++ .../typetest/property/optional/_model_base.py | 7 +++++++ .../typetest/property/valuetypes/_model_base.py | 7 +++++++ .../generated/typetest-union/typetest/union/_model_base.py | 7 +++++++ 38 files changed, 266 insertions(+) diff --git a/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 b/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 index db82e2de8e3..fa0dede097c 100644 --- a/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 +++ b/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 @@ -534,6 +534,13 @@ class Model(_MyMutableMapping): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py b/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py b/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py b/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py b/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py b/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py +++ b/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py +++ b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py +++ b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py b/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py +++ b/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py +++ b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py +++ b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py b/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py +++ b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py b/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py +++ b/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py b/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py +++ b/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py b/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py +++ b/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py b/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py +++ b/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py b/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py +++ b/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py b/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py +++ b/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py b/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py +++ b/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py b/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] diff --git a/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py b/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py index 05a6c6f41a4..8aeac6a88bb 100644 --- a/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py @@ -536,6 +536,13 @@ def _deserialize(cls, data, exist_discriminators): return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + result = {} if exclude_readonly: readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] From a09c52daf492d759f0da45c6211ae61ee4089574 Mon Sep 17 00:00:00 2001 From: tadelesh Date: Thu, 3 Aug 2023 17:21:46 +0800 Subject: [PATCH 07/13] refine type alias case --- .../codegen/templates/model_base.py.jinja2 | 29 +++++++++++---- .../authentication/apikey/_model_base.py | 35 +++++++++++-------- .../authentication/http/custom/_model_base.py | 35 +++++++++++-------- .../authentication/oauth2/_model_base.py | 35 +++++++++++-------- .../authentication/union/_model_base.py | 35 +++++++++++-------- .../core/internal/_model_base.py | 35 +++++++++++-------- .../_specs_/azure/core/basic/_model_base.py | 35 +++++++++++-------- .../azure/core/lro/rpc/legacy/_model_base.py | 35 +++++++++++-------- .../azure/core/lro/standard/_model_base.py | 35 +++++++++++-------- .../_specs_/azure/core/traits/_model_base.py | 35 +++++++++++-------- .../encode-bytes/encode/bytes/_model_base.py | 35 +++++++++++-------- .../encode/datetime/_model_base.py | 35 +++++++++++-------- .../encode/duration/_model_base.py | 35 +++++++++++-------- .../headasbooleanfalse/_model_base.py | 35 +++++++++++-------- .../headasbooleantrue/_model_base.py | 35 +++++++++++-------- .../parameters/bodyoptionality/_model_base.py | 35 +++++++++++-------- .../collectionformat/_model_base.py | 35 +++++++++++-------- .../parameters/spread/_model_base.py | 35 +++++++++++-------- .../projection/projectedname/_model_base.py | 35 +++++++++++-------- .../resiliency/srv/driven1/_model_base.py | 35 +++++++++++-------- .../resiliency/srv/driven2/_model_base.py | 35 +++++++++++-------- .../server/path/multiple/_model_base.py | 35 +++++++++++-------- .../server/path/single/_model_base.py | 35 +++++++++++-------- .../clientrequestid/_model_base.py | 35 +++++++++++-------- .../repeatability/_model_base.py | 35 +++++++++++-------- .../special-words/specialwords/_model_base.py | 35 +++++++++++-------- .../typetest/array/_model_base.py | 35 +++++++++++-------- .../typetest/dictionary/_model_base.py | 35 +++++++++++-------- .../typetest/enum/extensible/_model_base.py | 35 +++++++++++-------- .../typetest/enum/fixed/_model_base.py | 35 +++++++++++-------- .../typetest/model/empty/_model_base.py | 35 +++++++++++-------- .../typetest/model/inheritance/_model_base.py | 35 +++++++++++-------- .../typetest/model/usage/_model_base.py | 35 +++++++++++-------- .../typetest/model/visibility/_model_base.py | 35 +++++++++++-------- .../typetest/property/nullable/_model_base.py | 35 +++++++++++-------- .../typetest/property/optional/_model_base.py | 35 +++++++++++-------- .../property/valuetypes/_model_base.py | 35 +++++++++++-------- .../typetest/union/_model_base.py | 35 +++++++++++-------- 38 files changed, 762 insertions(+), 562 deletions(-) diff --git a/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 b/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 index fa0dede097c..42dd8b831c7 100644 --- a/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 +++ b/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 @@ -134,12 +134,11 @@ class AzureJSONEncoder(JSONEncoder): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,17 +302,28 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) +def _get_type_alias_type(module_name: str, alias_name: str): + types = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, typing._GenericAlias) # type: ignore + } + if alias_name not in types: + return alias_name + return types[alias_name] + + def _get_model(module_name: str, model_name: str): models = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, type) } module_end = module_name.rsplit(".", 1)[0] models.update({ k: v for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, type) }) if isinstance(model_name, str): model_name = model_name.split(".")[-1] @@ -575,6 +585,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -594,7 +609,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py b/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py b/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py b/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py b/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py b/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py +++ b/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py +++ b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py +++ b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py b/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py +++ b/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py +++ b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py +++ b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py b/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py +++ b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py b/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py +++ b/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py b/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py +++ b/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py b/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py +++ b/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py b/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py +++ b/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py b/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py +++ b/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py b/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py +++ b/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py b/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py +++ b/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py b/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass diff --git a/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py b/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py index 8aeac6a88bb..809f4ceceb6 100644 --- a/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py @@ -134,12 +134,11 @@ def __init__(self, *args, exclude_readonly: bool = False, **kwargs): def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - result = dict(o.items()) if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - for k in readonly_props: - result.pop(k, None) - return result + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -303,20 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) -def _get_model(module_name: str, model_name: str): - models = { +def _get_type_alias_type(module_name: str, alias_name: str): + types = { k: v for k, v in sys.modules[module_name].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore + if isinstance(v, typing._GenericAlias) # type: ignore } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - models.update( - { - k: v - for k, v in sys.modules[module_end].__dict__.items() - if isinstance(v, (type, typing._GenericAlias)) # type: ignore - } - ) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -571,6 +571,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): # type: ignore + if module is not None: + annotation = _get_type_alias_type(module, annotation) + # is it a forward ref / in quotes? if isinstance(annotation, (str, typing.ForwardRef)): try: @@ -590,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass From 0738321286aae8c4f0ad3a71b3f7a662c9a4ce4e Mon Sep 17 00:00:00 2001 From: tadelesh Date: Thu, 3 Aug 2023 17:25:19 +0800 Subject: [PATCH 08/13] fix --- .../autorest/codegen/templates/model_base.py.jinja2 | 2 +- .../authentication-api-key/authentication/apikey/_model_base.py | 2 +- .../authentication/http/custom/_model_base.py | 2 +- .../authentication-oauth2/authentication/oauth2/_model_base.py | 2 +- .../authentication-union/authentication/union/_model_base.py | 2 +- .../_specs_/azure/clientgenerator/core/internal/_model_base.py | 2 +- .../azure-core-basic/_specs_/azure/core/basic/_model_base.py | 2 +- .../_specs_/azure/core/lro/rpc/legacy/_model_base.py | 2 +- .../_specs_/azure/core/lro/standard/_model_base.py | 2 +- .../azure-core-traits/_specs_/azure/core/traits/_model_base.py | 2 +- .../test/generated/encode-bytes/encode/bytes/_model_base.py | 2 +- .../generated/encode-datetime/encode/datetime/_model_base.py | 2 +- .../generated/encode-duration/encode/duration/_model_base.py | 2 +- .../headasbooleanfalse/headasbooleanfalse/_model_base.py | 2 +- .../headasbooleantrue/headasbooleantrue/_model_base.py | 2 +- .../parameters/bodyoptionality/_model_base.py | 2 +- .../parameters/collectionformat/_model_base.py | 2 +- .../parameters-spread/parameters/spread/_model_base.py | 2 +- .../projection/projectedname/_model_base.py | 2 +- .../resiliency/srv/driven1/_model_base.py | 2 +- .../resiliency/srv/driven2/_model_base.py | 2 +- .../server-path-multiple/server/path/multiple/_model_base.py | 2 +- .../server-path-single/server/path/single/_model_base.py | 2 +- .../specialheaders/clientrequestid/_model_base.py | 2 +- .../specialheaders/repeatability/_model_base.py | 2 +- .../test/generated/special-words/specialwords/_model_base.py | 2 +- .../test/generated/typetest-array/typetest/array/_model_base.py | 2 +- .../typetest-dictionary/typetest/dictionary/_model_base.py | 2 +- .../typetest/enum/extensible/_model_base.py | 2 +- .../typetest-enum-fixed/typetest/enum/fixed/_model_base.py | 2 +- .../typetest-model-empty/typetest/model/empty/_model_base.py | 2 +- .../typetest/model/inheritance/_model_base.py | 2 +- .../typetest-model-usage/typetest/model/usage/_model_base.py | 2 +- .../typetest/model/visibility/_model_base.py | 2 +- .../typetest/property/nullable/_model_base.py | 2 +- .../typetest/property/optional/_model_base.py | 2 +- .../typetest/property/valuetypes/_model_base.py | 2 +- .../test/generated/typetest-union/typetest/union/_model_base.py | 2 +- 38 files changed, 38 insertions(+), 38 deletions(-) diff --git a/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 b/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 index 42dd8b831c7..ea50a2f1961 100644 --- a/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 +++ b/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 @@ -586,7 +586,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py b/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py b/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py b/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py b/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py b/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py +++ b/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-lro-rpc-legacy/_specs_/azure/core/lro/rpc/legacy/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py +++ b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py +++ b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py b/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py +++ b/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py +++ b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py +++ b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py b/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py +++ b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py b/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py +++ b/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py b/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py +++ b/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py b/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py +++ b/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py b/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py +++ b/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py b/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py +++ b/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py b/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py +++ b/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py b/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py +++ b/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py b/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-inheritance/typetest/model/inheritance/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) diff --git a/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py b/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py index 809f4ceceb6..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py @@ -572,7 +572,7 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur return None # is it a type alias? - if isinstance(annotation, str): # type: ignore + if isinstance(annotation, str): if module is not None: annotation = _get_type_alias_type(module, annotation) From c4638315b382200a44b23b6b8116c983567d9d07 Mon Sep 17 00:00:00 2001 From: tadelesh Date: Thu, 10 Aug 2023 17:50:10 +0800 Subject: [PATCH 09/13] update test --- .../lro/rpc/aio/_operations/_operations.py | 2 +- .../azurecore/lro/rpclegacy/_model_base.py | 120 +++-- .../lro/rpclegacy/_operations/_operations.py | 2 +- .../client/structure/service/_model_base.py | 120 +++-- .../structure/multiclient/_model_base.py | 120 +++-- .../structure/renamedoperation/_model_base.py | 120 +++-- .../twooperationgroup/_model_base.py | 120 +++-- .../payload/contentnegotiation/_model_base.py | 120 +++-- .../_operations/_operations.py | 4 +- .../aio/_operations/_operations.py | 4 +- .../model/notdiscriminated/_model_base.py | 120 +++-- .../_operations/_operations.py | 4 +- .../aio/_operations/_operations.py | 4 +- .../model/singlediscriminator/_model_base.py | 120 +++-- .../test/unittests/generated/model_base.py | 138 ++++-- .../test_model_base_serialization.py | 449 +++++++++++++++++- 16 files changed, 1239 insertions(+), 328 deletions(-) diff --git a/packages/typespec-python/test/generated/azurecore-lro-rpc/azurecore/lro/rpc/aio/_operations/_operations.py b/packages/typespec-python/test/generated/azurecore-lro-rpc/azurecore/lro/rpc/aio/_operations/_operations.py index d32dc0f8d54..5df16c59f19 100644 --- a/packages/typespec-python/test/generated/azurecore-lro-rpc/azurecore/lro/rpc/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/azurecore-lro-rpc/azurecore/lro/rpc/aio/_operations/_operations.py @@ -61,7 +61,7 @@ async def _long_running_rpc_initial(self, body: Union[_models.GenerationOptions, if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_rpc_long_running_rpc_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/azurecore-lro-rpclegacy/azurecore/lro/rpclegacy/_model_base.py b/packages/typespec-python/test/generated/azurecore-lro-rpclegacy/azurecore/lro/rpclegacy/_model_base.py index 48acb463cae..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/azurecore-lro-rpclegacy/azurecore/lro/rpclegacy/_model_base.py +++ b/packages/typespec-python/test/generated/azurecore-lro-rpclegacy/azurecore/lro/rpclegacy/_model_base.py @@ -128,10 +128,17 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -295,11 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) +def _get_type_alias_type(module_name: str, alias_name: str): + types = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, typing._GenericAlias) # type: ignore + } + if alias_name not in types: + return alias_name + return types[alias_name] + + def _get_model(module_name: str, model_name: str): models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -499,21 +516,51 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access + + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + if isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] + if isinstance(v, dict): + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements @@ -524,8 +571,22 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): + if module is not None: + annotation = _get_type_alias_type(module, annotation) + + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -534,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass @@ -552,22 +613,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +629,18 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] + + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: + try: + return _deserialize(deserializer, obj) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -680,7 +731,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e @@ -742,6 +793,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/azurecore-lro-rpclegacy/azurecore/lro/rpclegacy/_operations/_operations.py b/packages/typespec-python/test/generated/azurecore-lro-rpclegacy/azurecore/lro/rpclegacy/_operations/_operations.py index 21738ee004a..c5116e018ad 100644 --- a/packages/typespec-python/test/generated/azurecore-lro-rpclegacy/azurecore/lro/rpclegacy/_operations/_operations.py +++ b/packages/typespec-python/test/generated/azurecore-lro-rpclegacy/azurecore/lro/rpclegacy/_operations/_operations.py @@ -86,7 +86,7 @@ def _create_job_initial(self, body: Union[_models.JobData, JSON, IO], **kwargs: if isinstance(body, (IOBase, bytes)): _content = body else: - _content = json.dumps(body, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(body, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_legacy_create_job_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/client-structure-default/client/structure/service/_model_base.py b/packages/typespec-python/test/generated/client-structure-default/client/structure/service/_model_base.py index 48acb463cae..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/client-structure-default/client/structure/service/_model_base.py +++ b/packages/typespec-python/test/generated/client-structure-default/client/structure/service/_model_base.py @@ -128,10 +128,17 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -295,11 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) +def _get_type_alias_type(module_name: str, alias_name: str): + types = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, typing._GenericAlias) # type: ignore + } + if alias_name not in types: + return alias_name + return types[alias_name] + + def _get_model(module_name: str, model_name: str): models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -499,21 +516,51 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access + + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + if isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] + if isinstance(v, dict): + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements @@ -524,8 +571,22 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): + if module is not None: + annotation = _get_type_alias_type(module, annotation) + + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -534,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass @@ -552,22 +613,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +629,18 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] + + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: + try: + return _deserialize(deserializer, obj) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -680,7 +731,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e @@ -742,6 +793,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/client-structure-multiclient/client/structure/multiclient/_model_base.py b/packages/typespec-python/test/generated/client-structure-multiclient/client/structure/multiclient/_model_base.py index 48acb463cae..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/client-structure-multiclient/client/structure/multiclient/_model_base.py +++ b/packages/typespec-python/test/generated/client-structure-multiclient/client/structure/multiclient/_model_base.py @@ -128,10 +128,17 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -295,11 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) +def _get_type_alias_type(module_name: str, alias_name: str): + types = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, typing._GenericAlias) # type: ignore + } + if alias_name not in types: + return alias_name + return types[alias_name] + + def _get_model(module_name: str, model_name: str): models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -499,21 +516,51 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access + + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + if isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] + if isinstance(v, dict): + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements @@ -524,8 +571,22 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): + if module is not None: + annotation = _get_type_alias_type(module, annotation) + + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -534,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass @@ -552,22 +613,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +629,18 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] + + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: + try: + return _deserialize(deserializer, obj) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -680,7 +731,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e @@ -742,6 +793,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/client-structure-renamedoperation/client/structure/renamedoperation/_model_base.py b/packages/typespec-python/test/generated/client-structure-renamedoperation/client/structure/renamedoperation/_model_base.py index 48acb463cae..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/client-structure-renamedoperation/client/structure/renamedoperation/_model_base.py +++ b/packages/typespec-python/test/generated/client-structure-renamedoperation/client/structure/renamedoperation/_model_base.py @@ -128,10 +128,17 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -295,11 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) +def _get_type_alias_type(module_name: str, alias_name: str): + types = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, typing._GenericAlias) # type: ignore + } + if alias_name not in types: + return alias_name + return types[alias_name] + + def _get_model(module_name: str, model_name: str): models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -499,21 +516,51 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access + + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + if isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] + if isinstance(v, dict): + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements @@ -524,8 +571,22 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): + if module is not None: + annotation = _get_type_alias_type(module, annotation) + + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -534,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass @@ -552,22 +613,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +629,18 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] + + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: + try: + return _deserialize(deserializer, obj) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -680,7 +731,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e @@ -742,6 +793,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/client-structure-twooperationgroup/client/structure/twooperationgroup/_model_base.py b/packages/typespec-python/test/generated/client-structure-twooperationgroup/client/structure/twooperationgroup/_model_base.py index 48acb463cae..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/client-structure-twooperationgroup/client/structure/twooperationgroup/_model_base.py +++ b/packages/typespec-python/test/generated/client-structure-twooperationgroup/client/structure/twooperationgroup/_model_base.py @@ -128,10 +128,17 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -295,11 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) +def _get_type_alias_type(module_name: str, alias_name: str): + types = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, typing._GenericAlias) # type: ignore + } + if alias_name not in types: + return alias_name + return types[alias_name] + + def _get_model(module_name: str, model_name: str): models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -499,21 +516,51 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access + + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + if isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] + if isinstance(v, dict): + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements @@ -524,8 +571,22 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): + if module is not None: + annotation = _get_type_alias_type(module, annotation) + + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -534,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass @@ -552,22 +613,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +629,18 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] + + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: + try: + return _deserialize(deserializer, obj) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -680,7 +731,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e @@ -742,6 +793,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/payload-content-negotiation/payload/contentnegotiation/_model_base.py b/packages/typespec-python/test/generated/payload-content-negotiation/payload/contentnegotiation/_model_base.py index 48acb463cae..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/payload-content-negotiation/payload/contentnegotiation/_model_base.py +++ b/packages/typespec-python/test/generated/payload-content-negotiation/payload/contentnegotiation/_model_base.py @@ -128,10 +128,17 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -295,11 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) +def _get_type_alias_type(module_name: str, alias_name: str): + types = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, typing._GenericAlias) # type: ignore + } + if alias_name not in types: + return alias_name + return types[alias_name] + + def _get_model(module_name: str, model_name: str): models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -499,21 +516,51 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access + + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + if isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] + if isinstance(v, dict): + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements @@ -524,8 +571,22 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): + if module is not None: + annotation = _get_type_alias_type(module, annotation) + + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -534,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass @@ -552,22 +613,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +629,18 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] + + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: + try: + return _deserialize(deserializer, obj) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -680,7 +731,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e @@ -742,6 +793,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/typetest-model-nesteddiscriminator/typetest/model/nesteddiscriminator/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-nesteddiscriminator/typetest/model/nesteddiscriminator/_operations/_operations.py index 2923ab49431..0fa290c18ae 100644 --- a/packages/typespec-python/test/generated/typetest-model-nesteddiscriminator/typetest/model/nesteddiscriminator/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-nesteddiscriminator/typetest/model/nesteddiscriminator/_operations/_operations.py @@ -268,7 +268,7 @@ def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_nested_discriminator_put_model_request( content_type=content_type, @@ -436,7 +436,7 @@ def put_recursive_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_nested_discriminator_put_recursive_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-nesteddiscriminator/typetest/model/nesteddiscriminator/aio/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-nesteddiscriminator/typetest/model/nesteddiscriminator/aio/_operations/_operations.py index 4f0891b2efb..96f23d929f3 100644 --- a/packages/typespec-python/test/generated/typetest-model-nesteddiscriminator/typetest/model/nesteddiscriminator/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-nesteddiscriminator/typetest/model/nesteddiscriminator/aio/_operations/_operations.py @@ -188,7 +188,7 @@ async def put_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_nested_discriminator_put_model_request( content_type=content_type, @@ -356,7 +356,7 @@ async def put_recursive_model( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_nested_discriminator_put_recursive_model_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-notdiscriminated/typetest/model/notdiscriminated/_model_base.py b/packages/typespec-python/test/generated/typetest-model-notdiscriminated/typetest/model/notdiscriminated/_model_base.py index 48acb463cae..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/typetest-model-notdiscriminated/typetest/model/notdiscriminated/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-notdiscriminated/typetest/model/notdiscriminated/_model_base.py @@ -128,10 +128,17 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -295,11 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) +def _get_type_alias_type(module_name: str, alias_name: str): + types = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, typing._GenericAlias) # type: ignore + } + if alias_name not in types: + return alias_name + return types[alias_name] + + def _get_model(module_name: str, model_name: str): models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -499,21 +516,51 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access + + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + if isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] + if isinstance(v, dict): + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements @@ -524,8 +571,22 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): + if module is not None: + annotation = _get_type_alias_type(module, annotation) + + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -534,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass @@ -552,22 +613,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +629,18 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] + + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: + try: + return _deserialize(deserializer, obj) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -680,7 +731,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e @@ -742,6 +793,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/generated/typetest-model-notdiscriminated/typetest/model/notdiscriminated/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-notdiscriminated/typetest/model/notdiscriminated/_operations/_operations.py index 525cf144edf..5741b3bba0b 100644 --- a/packages/typespec-python/test/generated/typetest-model-notdiscriminated/typetest/model/notdiscriminated/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-notdiscriminated/typetest/model/notdiscriminated/_operations/_operations.py @@ -177,7 +177,7 @@ def post_valid( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_not_discriminated_post_valid_request( content_type=content_type, @@ -339,7 +339,7 @@ def put_valid(self, input: Union[_models.Siamese, JSON, IO], **kwargs: Any) -> _ if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_not_discriminated_put_valid_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-notdiscriminated/typetest/model/notdiscriminated/aio/_operations/_operations.py b/packages/typespec-python/test/generated/typetest-model-notdiscriminated/typetest/model/notdiscriminated/aio/_operations/_operations.py index fc5a170e549..e96ae0804ec 100644 --- a/packages/typespec-python/test/generated/typetest-model-notdiscriminated/typetest/model/notdiscriminated/aio/_operations/_operations.py +++ b/packages/typespec-python/test/generated/typetest-model-notdiscriminated/typetest/model/notdiscriminated/aio/_operations/_operations.py @@ -133,7 +133,7 @@ async def post_valid( # pylint: disable=inconsistent-return-statements if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_not_discriminated_post_valid_request( content_type=content_type, @@ -295,7 +295,7 @@ async def put_valid(self, input: Union[_models.Siamese, JSON, IO], **kwargs: Any if isinstance(input, (IOBase, bytes)): _content = input else: - _content = json.dumps(input, cls=AzureJSONEncoder) # type: ignore + _content = json.dumps(input, cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore request = build_not_discriminated_put_valid_request( content_type=content_type, diff --git a/packages/typespec-python/test/generated/typetest-model-singlediscriminator/typetest/model/singlediscriminator/_model_base.py b/packages/typespec-python/test/generated/typetest-model-singlediscriminator/typetest/model/singlediscriminator/_model_base.py index 48acb463cae..bff23a2376a 100644 --- a/packages/typespec-python/test/generated/typetest-model-singlediscriminator/typetest/model/singlediscriminator/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-singlediscriminator/typetest/model/singlediscriminator/_model_base.py @@ -128,10 +128,17 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -295,11 +302,21 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) +def _get_type_alias_type(module_name: str, alias_name: str): + types = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, typing._GenericAlias) # type: ignore + } + if alias_name not in types: + return alias_name + return types[alias_name] + + def _get_model(module_name: str, model_name: str): models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -499,21 +516,51 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if ( + isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators + ): # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access + + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + if isinstance(v, (list, tuple, set)): + return [Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v] + if isinstance(v, dict): + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements @@ -524,8 +571,22 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): + if module is not None: + annotation = _get_type_alias_type(module, annotation) + + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -534,7 +595,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass @@ -552,22 +613,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +629,18 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] + + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: + try: + return _deserialize(deserializer, obj) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -680,7 +731,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e @@ -742,6 +793,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/unittests/generated/model_base.py b/packages/typespec-python/test/unittests/generated/model_base.py index 48acb463cae..ea50a2f1961 100644 --- a/packages/typespec-python/test/unittests/generated/model_base.py +++ b/packages/typespec-python/test/unittests/generated/model_base.py @@ -128,10 +128,17 @@ def _is_readonly(p): class AzureJSONEncoder(JSONEncoder): """A JSON encoder that's capable of serializing datetime objects and bytes.""" + def __init__(self, *args, exclude_readonly: bool = False, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + def default(self, o): # pylint: disable=too-many-return-statements if _is_model(o): - readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] - return {k: v for k, v in o.items() if k not in readonly_props} + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + return {k: v for k, v in o.items() if k not in readonly_props} + else: + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -295,11 +302,29 @@ def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = return _DESERIALIZE_MAPPING.get(annotation) +def _get_type_alias_type(module_name: str, alias_name: str): + types = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, typing._GenericAlias) # type: ignore + } + if alias_name not in types: + return alias_name + return types[alias_name] + + def _get_model(module_name: str, model_name: str): - models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + models = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, type) + } module_end = module_name.rsplit(".", 1)[0] - module = sys.modules[module_end] - models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + models.update({ + k: v + for k, v in sys.modules[module_end].__dict__.items() + if isinstance(v, type) + }) if isinstance(model_name, str): model_name = model_name.split(".")[-1] if model_name not in models: @@ -499,21 +524,57 @@ def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member @classmethod - def _get_discriminator(cls) -> typing.Optional[str]: + def _get_discriminator(cls, exist_discriminators) -> typing.Optional[str]: for v in cls.__dict__.values(): - if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + if isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators: # pylint: disable=protected-access return v._rest_name # pylint: disable=protected-access return None @classmethod - def _deserialize(cls, data): + def _deserialize(cls, data, exist_discriminators): if not hasattr(cls, "__mapping__"): # pylint: disable=no-member return cls(data) - discriminator = cls._get_discriminator() - mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member + discriminator = cls._get_discriminator(exist_discriminators) + exist_discriminators.append(discriminator) + mapped_cls = cls.__mapping__.get( + data.get(discriminator), cls + ) # pylint: disable=no-member if mapped_cls == cls: return cls(data) - return mapped_cls._deserialize(data) # pylint: disable=protected-access + return mapped_cls._deserialize(data, exist_discriminators) # pylint: disable=protected-access + + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be JSONify using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + + result = {} + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: # pyright: reportUnboundVariable=false + continue + result[k] = Model._as_dict_value(v, exclude_readonly=exclude_readonly) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + if isinstance(v, (list, tuple, set)): + return [ + Model._as_dict_value(x, exclude_readonly=exclude_readonly) + for x in v + ] + if isinstance(v, dict): + return { + dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) + for dk, dv in v.items() + } + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements @@ -524,8 +585,22 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur if not annotation or annotation in [int, float]: return None + # is it a type alias? + if isinstance(annotation, str): + if module is not None: + annotation = _get_type_alias_type(module, annotation) + + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + try: - if module and _is_model(_get_model(module, annotation)): + if module and _is_model(annotation): if rf: rf._is_model = True @@ -534,7 +609,7 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj return obj return _deserialize(model_deserializer, obj) - return functools.partial(_deserialize_model, _get_model(module, annotation)) + return functools.partial(_deserialize_model, annotation) except Exception: pass @@ -552,22 +627,8 @@ def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj except AttributeError: pass - if getattr(annotation, "__origin__", None) is typing.Union: - - def _deserialize_with_union(union_annotation, obj): - for t in union_annotation.__args__: - try: - return _deserialize(t, obj, module, rf) - except DeserializationError: - pass - raise DeserializationError() - - return functools.partial(_deserialize_with_union, annotation) - # is it optional? try: - # right now, assuming we don't have unions, since we're getting rid of the only - # union we used to have in msrest models, which was union of str and enum if any(a for a in annotation.__args__ if a == type(None)): if_obj_deserializer = _get_deserialize_callable_from_annotation( next(a for a in annotation.__args__ if a != type(None)), module, rf @@ -582,14 +643,18 @@ def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Calla except AttributeError: pass - # is it a forward ref / in quotes? - if isinstance(annotation, (str, typing.ForwardRef)): - try: - model_name = annotation.__forward_arg__ # type: ignore - except AttributeError: - model_name = annotation - if module is not None: - annotation = _get_model(module, model_name) + if getattr(annotation, "__origin__", None) is typing.Union: + deserializers = [_get_deserialize_callable_from_annotation(arg, module, rf) for arg in annotation.__args__] + + def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: + try: + return _deserialize(deserializer, obj) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, deserializers) try: if annotation._name == "Dict": @@ -680,7 +745,7 @@ def _deserialize_with_callable( # for unknown value, return raw value return value if isinstance(deserializer, type) and issubclass(deserializer, Model): - return deserializer._deserialize(value) + return deserializer._deserialize(value, []) return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) except Exception as e: raise DeserializationError() from e @@ -742,6 +807,7 @@ def __set__(self, obj: Model, value) -> None: return if self._is_model and not _is_model(value): obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + return obj.__setitem__(self._rest_name, _serialize(value, self._format)) def _get_deserialize_callable_from_annotation( diff --git a/packages/typespec-python/test/unittests/test_model_base_serialization.py b/packages/typespec-python/test/unittests/test_model_base_serialization.py index 03b1653b05b..06474fee6a9 100644 --- a/packages/typespec-python/test/unittests/test_model_base_serialization.py +++ b/packages/typespec-python/test/unittests/test_model_base_serialization.py @@ -5,10 +5,12 @@ import copy import json import datetime -from typing import Any, Iterable, List, Literal, Dict, Mapping, Sequence, Set, Tuple, Optional, overload +from typing import Any, Iterable, List, Literal, Dict, Mapping, Sequence, Set, Tuple, Optional, overload, Union import pytest import isodate -from generated.model_base import AzureJSONEncoder, Model, rest_field +from azure.core.serialization import NULL + +from generated.model_base import AzureJSONEncoder, Model, rest_field, _is_model, rest_discriminator class BasicResource(Model): @@ -873,8 +875,7 @@ def test_model_recursion_complex(): assert isinstance(model.list_of_dict_of_me[0], Dict) assert isinstance(model.list_of_dict_of_me[0]["me"], RecursiveModel) - assert json.loads(json.dumps(dict(model))) == model == dict_response - assert json.loads(json.dumps(model, cls=AzureJSONEncoder)) == model == dict_response + assert model.as_dict() == model == dict_response def test_literals(): @@ -1855,9 +1856,26 @@ def test_deserialization_is(): assert x.y.z.zval == isodate.parse_datetime(serialized_datetime) +class InnerModelWithReadonly(Model): + normal_property: str = rest_field(name="normalProperty") + readonly_property: str = rest_field(name="readonlyProperty", visibility=["read"]) + + @overload + def __init__(self, *, normal_property: str): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any], /): + ... + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + class ModelWithReadonly(Model): normal_property: str = rest_field(name="normalProperty") readonly_property: str = rest_field(name="readonlyProperty", visibility=["read"]) + inner_model: InnerModelWithReadonly = rest_field(name="innerModel") @overload def __init__(self, *, normal_property: str): @@ -1873,25 +1891,62 @@ def __init__(self, *args, **kwargs): def test_readonly(): # we pass the dict to json, so readonly shouldn't show up in the JSON version - model = ModelWithReadonly({"normalProperty": "normal", "readonlyProperty": "readonly"}) - assert json.loads(json.dumps(model, cls=AzureJSONEncoder)) == {"normalProperty": "normal"} - assert model == {"normalProperty": "normal", "readonlyProperty": "readonly"} + value = { + "normalProperty": "normal", + "readonlyProperty": "readonly", + "innerModel": { + "normalProperty": "normal", + "readonlyProperty": "readonly" + } + } + model = ModelWithReadonly(value) + assert model.as_dict(exclude_readonly=True) == {"normalProperty": "normal", + "innerModel": {"normalProperty": "normal"}} + assert json.loads(json.dumps(model, cls=AzureJSONEncoder)) == value + assert model == value assert model["readonlyProperty"] == model.readonly_property == "readonly" + assert model["innerModel"]["readonlyProperty"] == model.inner_model.readonly_property == "readonly" def test_readonly_set(): - model = ModelWithReadonly({"normalProperty": "normal", "readonlyProperty": "readonly"}) + value = { + "normalProperty": "normal", + "readonlyProperty": "readonly", + "innerModel": { + "normalProperty": "normal", + "readonlyProperty": "readonly" + } + } + + model = ModelWithReadonly(value) assert model.normal_property == model["normalProperty"] == "normal" assert model.readonly_property == model["readonlyProperty"] == "readonly" + assert model.inner_model.normal_property == model.inner_model["normalProperty"] == "normal" + assert model.inner_model.readonly_property == model.inner_model["readonlyProperty"] == "readonly" - assert json.loads(json.dumps(model, cls=AzureJSONEncoder)) == {"normalProperty": "normal"} + assert model.as_dict(exclude_readonly=True) == {"normalProperty": "normal", + "innerModel": {"normalProperty": "normal"}} + assert json.loads(json.dumps(model, cls=AzureJSONEncoder)) == value model["normalProperty"] = "setWithDict" model["readonlyProperty"] = "setWithDict" + model.inner_model["normalProperty"] = "setWithDict" + model.inner_model["readonlyProperty"] = "setWithDict" assert model.normal_property == model["normalProperty"] == "setWithDict" assert model.readonly_property == model["readonlyProperty"] == "setWithDict" - assert json.loads(json.dumps(model, cls=AzureJSONEncoder)) == {"normalProperty": "setWithDict"} + assert model.inner_model.normal_property == model.inner_model["normalProperty"] == "setWithDict" + assert model.inner_model.readonly_property == model.inner_model["readonlyProperty"] == "setWithDict" + assert model.as_dict(exclude_readonly=True) == {"normalProperty": "setWithDict", + "innerModel": {"normalProperty": "setWithDict"}} + assert json.loads(json.dumps(model, cls=AzureJSONEncoder)) == { + "normalProperty": "setWithDict", + "readonlyProperty": "setWithDict", + "innerModel": { + "normalProperty": "setWithDict", + "readonlyProperty": "setWithDict" + } + } def test_incorrect_initialization(): @@ -3444,3 +3499,377 @@ def __init__(self, *args, **kwargs): assert model.required_property is None with pytest.raises(KeyError): model["requiredProperty"] + + +def test_null_serilization(): + dict_response = { + "name": "it's me!", + "listOfMe": [ + { + "name": "it's me!", + } + ], + "dictOfMe": { + "me": { + "name": "it's me!", + } + }, + "dictOfListOfMe": { + "many mes": [ + { + "name": "it's me!", + } + ] + }, + "listOfDictOfMe": None + } + model = RecursiveModel(dict_response) + assert json.loads(json.dumps(model, cls=AzureJSONEncoder)) == dict_response + + assert model.as_dict() == dict_response + + model.list_of_me = NULL + model.dict_of_me = None + model.list_of_dict_of_me = [ + { + "me": { + "name": "it's me!", + } + } + ] + model.dict_of_list_of_me["many mes"][0].list_of_me = NULL + model.dict_of_list_of_me["many mes"][0].dict_of_me = None + model.list_of_dict_of_me[0]["me"].list_of_me = NULL + model.list_of_dict_of_me[0]["me"].dict_of_me = None + + assert json.loads(json.dumps(model, cls=AzureJSONEncoder)) == { + "name": "it's me!", + "listOfMe": None, + "dictOfListOfMe": { + "many mes": [ + { + "name": "it's me!", + "listOfMe": None, + } + ] + }, + "listOfDictOfMe": [ + { + "me": { + "name": "it's me!", + "listOfMe": None, + } + } + ] + } + + assert model.as_dict() == { + "name": "it's me!", + "listOfMe": None, + "dictOfListOfMe": { + "many mes": [ + { + "name": "it's me!", + "listOfMe": None, + } + ] + }, + "listOfDictOfMe": [ + { + "me": { + "name": "it's me!", + "listOfMe": None, + } + } + ] + } + + +class UnionBaseModel(Model): + name: str = rest_field() + + @overload + def __init__(self, *, name: str): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + ... + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class UnionModel1(UnionBaseModel): + prop1: int = rest_field() + + @overload + def __init__(self, *, name: str, prop1: int): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + ... + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class UnionModel2(UnionBaseModel): + prop2: int = rest_field() + + @overload + def __init__(self, *, name: str, prop2: int): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + ... + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +MyNamedUnion = Union["UnionModel1", "UnionModel2"] + + +class ModelWithNamedUnionProperty(Model): + named_union: "MyNamedUnion" = rest_field(name="namedUnion") + + @overload + def __init__(self, *, named_union: "MyNamedUnion"): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + ... + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ModelWithSimpleUnionProperty(Model): + simple_union: Union[int, List[int]] = rest_field(name="simpleUnion") + + @overload + def __init__(self, *, simple_union: Union[int, List[int]]): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + ... + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +def test_union(): + simple = ModelWithSimpleUnionProperty(simple_union=1) + assert simple.simple_union == simple["simpleUnion"] == 1 + simple = ModelWithSimpleUnionProperty(simple_union=[1, 2]) + assert simple.simple_union == simple["simpleUnion"] == [1, 2] + named = ModelWithNamedUnionProperty() + assert not _is_model(named.named_union) + named.named_union = UnionModel1(name="model1", prop1=1) + assert _is_model(named.named_union) + assert named.named_union == named["namedUnion"] == {"name": "model1", "prop1": 1} + named = ModelWithNamedUnionProperty(named_union=UnionModel2(name="model2", prop2=2)) + assert named.named_union == named["namedUnion"] == {"name": "model2", "prop2": 2} + named = ModelWithNamedUnionProperty({"namedUnion": {"name": "model2", "prop2": 2}}) + assert named.named_union == named["namedUnion"] == {"name": "model2", "prop2": 2} + + +def test_as_dict(): + class CatComplex(PetComplex): + color: Optional[str] = rest_field(default=None) + hates: Optional[List[DogComplex]] = rest_field(default=None, visibility=["read"]) + + @overload + def __init__( + self, + *, + id: Optional[int] = None, + name: Optional[str] = None, + food: Optional[str] = None, + color: Optional[str] = None, + hates: Optional[List[DogComplex]] = None, + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any], /): + ... + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + model = CatComplex(id=2, name="Siameeee", hates=[ + DogComplex(id=1, name="Potato", food="tomato"), + DogComplex(id=-1, name="Tomato", food="french fries") + ]) + assert model.as_dict(exclude_readonly=True) == { + "id": 2, + "name": "Siameeee", + "color": None + } + + +class Fish(Model): + __mapping__: Dict[str, Model] = {} + age: int = rest_field() + kind: Literal[None] = rest_discriminator(name="kind") + + @overload + def __init__(self, *, age: int, ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + ... + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.kind: Literal[None] = None + + +class Shark(Fish, discriminator="shark"): + __mapping__: Dict[str, Model] = {} + kind: Literal["shark"] = rest_discriminator(name="kind") + sharktype: Literal[None] = rest_discriminator(name="sharktype") + + @overload + def __init__(self, *, age: int, ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + ... + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.kind: Literal["shark"] = "shark" + self.sharktype: Literal[None] = None + + +class GoblinShark(Shark, discriminator="goblin"): + sharktype: Literal["goblin"] = rest_discriminator(name="sharktype") + + @overload + def __init__(self, *, age: int, ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + ... + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.sharktype: Literal["goblin"] = "goblin" + + +class Salmon(Fish, discriminator="salmon"): + kind: Literal["salmon"] = rest_discriminator(name="kind") + friends: Optional[List["Fish"]] = rest_field() + hate: Optional[Dict[str, "Fish"]] = rest_field() + partner: Optional["Fish"] = rest_field() + + @overload + def __init__( + self, + *, + age: int, + friends: Optional[List["Fish"]] = None, + hate: Optional[Dict[str, "Fish"]] = None, + partner: Optional["Fish"] = None, + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + ... + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.kind: Literal["salmon"] = "salmon" + + +class SawShark(Shark, discriminator="saw"): + sharktype: Literal["saw"] = rest_discriminator(name="sharktype") + + @overload + def __init__(self, *, age: int, ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + ... + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.sharktype: Literal["saw"] = "saw" + + +def test_discriminator(): + input = { + "age": 1, + "kind": "salmon", + "partner": { + "age": 2, + "kind": "shark", + "sharktype": "saw", + }, + "friends": [ + { + "age": 2, + "kind": "salmon", + "partner": { + "age": 3, + "kind": "salmon", + }, + "hate": { + "key1": { + "age": 4, + "kind": "salmon", + }, + "key2": { + "age": 2, + "kind": "shark", + "sharktype": "goblin", + }, + }, + }, + { + "age": 3, + "kind": "shark", + "sharktype": "goblin", + }, + ], + "hate": { + "key3": { + "age": 3, + "kind": "shark", + "sharktype": "saw", + }, + "key4": { + "age": 2, + "kind": "salmon", + "friends": [ + { + "age": 1, + "kind": "salmon", + }, + { + "age": 4, + "kind": "shark", + "sharktype": "goblin", + }, + ], + }, + }, + } + + model = Salmon(input) + assert model == input + assert model.partner.age == 2 + assert model.partner == SawShark(age=2) + assert model.friends[0].hate["key2"] == GoblinShark(age=2) From 31d3cfefd8a09fd5196e228859b60017589d1edc Mon Sep 17 00:00:00 2001 From: tadelesh Date: Thu, 10 Aug 2023 18:16:07 +0800 Subject: [PATCH 10/13] update ser/deser --- .../autorest/codegen/templates/model_base.py.jinja2 | 10 +++++++--- .../authentication/apikey/_model_base.py | 10 +++++++--- .../authentication/http/custom/_model_base.py | 10 +++++++--- .../authentication/oauth2/_model_base.py | 10 +++++++--- .../authentication/union/_model_base.py | 10 +++++++--- .../azure/clientgenerator/core/internal/_model_base.py | 10 +++++++--- .../_specs_/azure/core/basic/_model_base.py | 10 +++++++--- .../_specs_/azure/core/lro/standard/_model_base.py | 10 +++++++--- .../_specs_/azure/core/traits/_model_base.py | 10 +++++++--- .../azurecore-lro-rpc/azurecore/lro/rpc/_model_base.py | 10 +++++++--- .../azurecore/lro/rpclegacy/_model_base.py | 10 +++++++--- .../client/structure/service/_model_base.py | 10 +++++++--- .../client/structure/multiclient/_model_base.py | 10 +++++++--- .../client/structure/renamedoperation/_model_base.py | 10 +++++++--- .../client/structure/twooperationgroup/_model_base.py | 10 +++++++--- .../generated/encode-bytes/encode/bytes/_model_base.py | 10 +++++++--- .../encode-datetime/encode/datetime/_model_base.py | 10 +++++++--- .../encode-duration/encode/duration/_model_base.py | 10 +++++++--- .../headasbooleanfalse/_model_base.py | 10 +++++++--- .../headasbooleantrue/headasbooleantrue/_model_base.py | 10 +++++++--- .../parameters/bodyoptionality/_model_base.py | 10 +++++++--- .../parameters/collectionformat/_model_base.py | 10 +++++++--- .../parameters-spread/parameters/spread/_model_base.py | 10 +++++++--- .../payload/contentnegotiation/_model_base.py | 10 +++++++--- .../projection/projectedname/_model_base.py | 10 +++++++--- .../resiliency/srv/driven1/_model_base.py | 10 +++++++--- .../resiliency/srv/driven2/_model_base.py | 10 +++++++--- .../server/path/multiple/_model_base.py | 10 +++++++--- .../server/path/single/_model_base.py | 10 +++++++--- .../specialheaders/clientrequestid/_model_base.py | 10 +++++++--- .../specialheaders/repeatability/_model_base.py | 10 +++++++--- .../special-words/specialwords/_model_base.py | 10 +++++++--- .../typetest-array/typetest/array/_model_base.py | 10 +++++++--- .../typetest/dictionary/_model_base.py | 10 +++++++--- .../typetest/enum/extensible/_model_base.py | 10 +++++++--- .../typetest/enum/fixed/_model_base.py | 10 +++++++--- .../typetest/model/empty/_model_base.py | 10 +++++++--- .../typetest/model/nesteddiscriminator/_model_base.py | 10 +++++++--- .../typetest/model/notdiscriminated/_model_base.py | 10 +++++++--- .../typetest/model/singlediscriminator/_model_base.py | 10 +++++++--- .../typetest/model/usage/_model_base.py | 10 +++++++--- .../typetest/model/visibility/_model_base.py | 10 +++++++--- .../typetest/property/nullable/_model_base.py | 10 +++++++--- .../typetest/property/optional/_model_base.py | 10 +++++++--- .../typetest/property/valuetypes/_model_base.py | 10 +++++++--- .../typetest-union/typetest/union/_model_base.py | 10 +++++++--- .../test/unittests/generated/model_base.py | 10 +++++++--- 47 files changed, 329 insertions(+), 141 deletions(-) diff --git a/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 b/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 index ea50a2f1961..e9c4d0289ba 100644 --- a/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 +++ b/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 @@ -486,7 +486,7 @@ class Model(_MyMutableMapping): raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -795,6 +795,8 @@ class _RestField: item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -805,8 +807,10 @@ class _RestField: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py b/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py b/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py b/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py b/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py b/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py +++ b/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/azurecore-lro-rpc/azurecore/lro/rpc/_model_base.py b/packages/typespec-python/test/generated/azurecore-lro-rpc/azurecore/lro/rpc/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/azurecore-lro-rpc/azurecore/lro/rpc/_model_base.py +++ b/packages/typespec-python/test/generated/azurecore-lro-rpc/azurecore/lro/rpc/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/azurecore-lro-rpclegacy/azurecore/lro/rpclegacy/_model_base.py b/packages/typespec-python/test/generated/azurecore-lro-rpclegacy/azurecore/lro/rpclegacy/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/azurecore-lro-rpclegacy/azurecore/lro/rpclegacy/_model_base.py +++ b/packages/typespec-python/test/generated/azurecore-lro-rpclegacy/azurecore/lro/rpclegacy/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/client-structure-default/client/structure/service/_model_base.py b/packages/typespec-python/test/generated/client-structure-default/client/structure/service/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/client-structure-default/client/structure/service/_model_base.py +++ b/packages/typespec-python/test/generated/client-structure-default/client/structure/service/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/client-structure-multiclient/client/structure/multiclient/_model_base.py b/packages/typespec-python/test/generated/client-structure-multiclient/client/structure/multiclient/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/client-structure-multiclient/client/structure/multiclient/_model_base.py +++ b/packages/typespec-python/test/generated/client-structure-multiclient/client/structure/multiclient/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/client-structure-renamedoperation/client/structure/renamedoperation/_model_base.py b/packages/typespec-python/test/generated/client-structure-renamedoperation/client/structure/renamedoperation/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/client-structure-renamedoperation/client/structure/renamedoperation/_model_base.py +++ b/packages/typespec-python/test/generated/client-structure-renamedoperation/client/structure/renamedoperation/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/client-structure-twooperationgroup/client/structure/twooperationgroup/_model_base.py b/packages/typespec-python/test/generated/client-structure-twooperationgroup/client/structure/twooperationgroup/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/client-structure-twooperationgroup/client/structure/twooperationgroup/_model_base.py +++ b/packages/typespec-python/test/generated/client-structure-twooperationgroup/client/structure/twooperationgroup/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py +++ b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py +++ b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py b/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py +++ b/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py +++ b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py +++ b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py b/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/payload-content-negotiation/payload/contentnegotiation/_model_base.py b/packages/typespec-python/test/generated/payload-content-negotiation/payload/contentnegotiation/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/payload-content-negotiation/payload/contentnegotiation/_model_base.py +++ b/packages/typespec-python/test/generated/payload-content-negotiation/payload/contentnegotiation/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py +++ b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py b/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py +++ b/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py b/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py +++ b/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py b/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py +++ b/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py b/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py +++ b/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py b/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py +++ b/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py b/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py +++ b/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py b/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py +++ b/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py b/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/typetest-model-nesteddiscriminator/typetest/model/nesteddiscriminator/_model_base.py b/packages/typespec-python/test/generated/typetest-model-nesteddiscriminator/typetest/model/nesteddiscriminator/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/typetest-model-nesteddiscriminator/typetest/model/nesteddiscriminator/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-nesteddiscriminator/typetest/model/nesteddiscriminator/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/typetest-model-notdiscriminated/typetest/model/notdiscriminated/_model_base.py b/packages/typespec-python/test/generated/typetest-model-notdiscriminated/typetest/model/notdiscriminated/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/typetest-model-notdiscriminated/typetest/model/notdiscriminated/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-notdiscriminated/typetest/model/notdiscriminated/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/typetest-model-singlediscriminator/typetest/model/singlediscriminator/_model_base.py b/packages/typespec-python/test/generated/typetest-model-singlediscriminator/typetest/model/singlediscriminator/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/typetest-model-singlediscriminator/typetest/model/singlediscriminator/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-singlediscriminator/typetest/model/singlediscriminator/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py b/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py index bff23a2376a..50b93b4941d 100644 --- a/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py @@ -478,7 +478,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -781,6 +781,8 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item + if self._is_model: + return item return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: @@ -791,8 +793,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) diff --git a/packages/typespec-python/test/unittests/generated/model_base.py b/packages/typespec-python/test/unittests/generated/model_base.py index ea50a2f1961..9468f53ff52 100644 --- a/packages/typespec-python/test/unittests/generated/model_base.py +++ b/packages/typespec-python/test/unittests/generated/model_base.py @@ -795,7 +795,9 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin item = obj.get(self._rest_name) if item is None: return item - return _deserialize(self._type, _serialize(item, self._format), rf=self) + if self._is_model: + return item + return _deserialize(self._type, item, rf=self) def __set__(self, obj: Model, value) -> None: if value is None: @@ -805,8 +807,10 @@ def __set__(self, obj: Model, value) -> None: except KeyError: pass return - if self._is_model and not _is_model(value): - obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) return obj.__setitem__(self._rest_name, _serialize(value, self._format)) From d12da76a2cc4f14bde50a801393089ce46ac6838 Mon Sep 17 00:00:00 2001 From: tadelesh Date: Thu, 10 Aug 2023 20:21:16 +0800 Subject: [PATCH 11/13] update unittest --- .../typespec-python/test/unittests/generated/model_base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/typespec-python/test/unittests/generated/model_base.py b/packages/typespec-python/test/unittests/generated/model_base.py index 9468f53ff52..e9c4d0289ba 100644 --- a/packages/typespec-python/test/unittests/generated/model_base.py +++ b/packages/typespec-python/test/unittests/generated/model_base.py @@ -486,7 +486,7 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") dict_to_pass.update( { - self._attr_to_rest_field[k]._rest_name: _serialize(v, self._attr_to_rest_field[k]._format) + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) for k, v in kwargs.items() if v is not None } @@ -797,7 +797,7 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin return item if self._is_model: return item - return _deserialize(self._type, item, rf=self) + return _deserialize(self._type, _serialize(item, self._format), rf=self) def __set__(self, obj: Model, value) -> None: if value is None: From 75370e3cd3ffb6d23a19ffa607288c21663a058f Mon Sep 17 00:00:00 2001 From: tadelesh Date: Fri, 11 Aug 2023 10:57:24 +0800 Subject: [PATCH 12/13] fix lint --- .../autorest/codegen/templates/model_base.py.jinja2 | 5 ++--- .../authentication/apikey/_model_base.py | 5 ++--- .../authentication/http/custom/_model_base.py | 5 ++--- .../authentication/oauth2/_model_base.py | 5 ++--- .../authentication-union/authentication/union/_model_base.py | 5 ++--- .../azure/clientgenerator/core/internal/_model_base.py | 5 ++--- .../azure-core-basic/_specs_/azure/core/basic/_model_base.py | 5 ++--- .../_specs_/azure/core/lro/standard/_model_base.py | 5 ++--- .../_specs_/azure/core/traits/_model_base.py | 5 ++--- .../azurecore-lro-rpc/azurecore/lro/rpc/_model_base.py | 5 ++--- .../azurecore/lro/rpclegacy/_model_base.py | 5 ++--- .../client/structure/service/_model_base.py | 5 ++--- .../client/structure/multiclient/_model_base.py | 5 ++--- .../client/structure/renamedoperation/_model_base.py | 5 ++--- .../client/structure/twooperationgroup/_model_base.py | 5 ++--- .../test/generated/encode-bytes/encode/bytes/_model_base.py | 5 ++--- .../generated/encode-datetime/encode/datetime/_model_base.py | 5 ++--- .../generated/encode-duration/encode/duration/_model_base.py | 5 ++--- .../headasbooleanfalse/headasbooleanfalse/_model_base.py | 5 ++--- .../headasbooleantrue/headasbooleantrue/_model_base.py | 5 ++--- .../parameters/bodyoptionality/_model_base.py | 5 ++--- .../parameters/collectionformat/_model_base.py | 5 ++--- .../parameters-spread/parameters/spread/_model_base.py | 5 ++--- .../payload/contentnegotiation/_model_base.py | 5 ++--- .../projection/projectedname/_model_base.py | 5 ++--- .../resiliency/srv/driven1/_model_base.py | 5 ++--- .../resiliency/srv/driven2/_model_base.py | 5 ++--- .../server-path-multiple/server/path/multiple/_model_base.py | 5 ++--- .../server-path-single/server/path/single/_model_base.py | 5 ++--- .../specialheaders/clientrequestid/_model_base.py | 5 ++--- .../specialheaders/repeatability/_model_base.py | 5 ++--- .../test/generated/special-words/specialwords/_model_base.py | 5 ++--- .../generated/typetest-array/typetest/array/_model_base.py | 5 ++--- .../typetest-dictionary/typetest/dictionary/_model_base.py | 5 ++--- .../typetest/enum/extensible/_model_base.py | 5 ++--- .../typetest-enum-fixed/typetest/enum/fixed/_model_base.py | 5 ++--- .../typetest-model-empty/typetest/model/empty/_model_base.py | 5 ++--- .../typetest/model/nesteddiscriminator/_model_base.py | 5 ++--- .../typetest/model/notdiscriminated/_model_base.py | 5 ++--- .../typetest/model/singlediscriminator/_model_base.py | 5 ++--- .../typetest-model-usage/typetest/model/usage/_model_base.py | 5 ++--- .../typetest/model/visibility/_model_base.py | 5 ++--- .../typetest/property/nullable/_model_base.py | 5 ++--- .../typetest/property/optional/_model_base.py | 5 ++--- .../typetest/property/valuetypes/_model_base.py | 5 ++--- .../generated/typetest-union/typetest/union/_model_base.py | 5 ++--- 46 files changed, 92 insertions(+), 138 deletions(-) diff --git a/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 b/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 index e9c4d0289ba..17c08a23b49 100644 --- a/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 +++ b/packages/autorest.python/autorest/codegen/templates/model_base.py.jinja2 @@ -137,8 +137,7 @@ class AzureJSONEncoder(JSONEncoder): if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -577,7 +576,7 @@ class Model(_MyMutableMapping): return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py b/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-api-key/authentication/apikey/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py b/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-http-custom/authentication/http/custom/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py b/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-oauth2/authentication/oauth2/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py b/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py +++ b/packages/typespec-python/test/generated/authentication-union/authentication/union/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py b/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py +++ b/packages/typespec-python/test/generated/azure-client-generator-core-internal/_specs_/azure/clientgenerator/core/internal/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-basic/_specs_/azure/core/basic/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-lro-standard/_specs_/azure/core/lro/standard/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py +++ b/packages/typespec-python/test/generated/azure-core-traits/_specs_/azure/core/traits/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/azurecore-lro-rpc/azurecore/lro/rpc/_model_base.py b/packages/typespec-python/test/generated/azurecore-lro-rpc/azurecore/lro/rpc/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/azurecore-lro-rpc/azurecore/lro/rpc/_model_base.py +++ b/packages/typespec-python/test/generated/azurecore-lro-rpc/azurecore/lro/rpc/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/azurecore-lro-rpclegacy/azurecore/lro/rpclegacy/_model_base.py b/packages/typespec-python/test/generated/azurecore-lro-rpclegacy/azurecore/lro/rpclegacy/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/azurecore-lro-rpclegacy/azurecore/lro/rpclegacy/_model_base.py +++ b/packages/typespec-python/test/generated/azurecore-lro-rpclegacy/azurecore/lro/rpclegacy/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/client-structure-default/client/structure/service/_model_base.py b/packages/typespec-python/test/generated/client-structure-default/client/structure/service/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/client-structure-default/client/structure/service/_model_base.py +++ b/packages/typespec-python/test/generated/client-structure-default/client/structure/service/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/client-structure-multiclient/client/structure/multiclient/_model_base.py b/packages/typespec-python/test/generated/client-structure-multiclient/client/structure/multiclient/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/client-structure-multiclient/client/structure/multiclient/_model_base.py +++ b/packages/typespec-python/test/generated/client-structure-multiclient/client/structure/multiclient/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/client-structure-renamedoperation/client/structure/renamedoperation/_model_base.py b/packages/typespec-python/test/generated/client-structure-renamedoperation/client/structure/renamedoperation/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/client-structure-renamedoperation/client/structure/renamedoperation/_model_base.py +++ b/packages/typespec-python/test/generated/client-structure-renamedoperation/client/structure/renamedoperation/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/client-structure-twooperationgroup/client/structure/twooperationgroup/_model_base.py b/packages/typespec-python/test/generated/client-structure-twooperationgroup/client/structure/twooperationgroup/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/client-structure-twooperationgroup/client/structure/twooperationgroup/_model_base.py +++ b/packages/typespec-python/test/generated/client-structure-twooperationgroup/client/structure/twooperationgroup/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py +++ b/packages/typespec-python/test/generated/encode-bytes/encode/bytes/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py +++ b/packages/typespec-python/test/generated/encode-datetime/encode/datetime/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py b/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py +++ b/packages/typespec-python/test/generated/encode-duration/encode/duration/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py +++ b/packages/typespec-python/test/generated/headasbooleanfalse/headasbooleanfalse/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py +++ b/packages/typespec-python/test/generated/headasbooleantrue/headasbooleantrue/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-body-optionality/parameters/bodyoptionality/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py b/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-collection-format/parameters/collectionformat/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py +++ b/packages/typespec-python/test/generated/parameters-spread/parameters/spread/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/payload-content-negotiation/payload/contentnegotiation/_model_base.py b/packages/typespec-python/test/generated/payload-content-negotiation/payload/contentnegotiation/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/payload-content-negotiation/payload/contentnegotiation/_model_base.py +++ b/packages/typespec-python/test/generated/payload-content-negotiation/payload/contentnegotiation/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py +++ b/packages/typespec-python/test/generated/projection-projected-name/projection/projectedname/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py b/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py +++ b/packages/typespec-python/test/generated/resiliency-srv-driven1/resiliency/srv/driven1/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py b/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py +++ b/packages/typespec-python/test/generated/resiliency-srv-driven2/resiliency/srv/driven2/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py b/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py +++ b/packages/typespec-python/test/generated/server-path-multiple/server/path/multiple/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py b/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py +++ b/packages/typespec-python/test/generated/server-path-single/server/path/single/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py b/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py +++ b/packages/typespec-python/test/generated/special-headers-client-request-id/specialheaders/clientrequestid/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py b/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py +++ b/packages/typespec-python/test/generated/special-headers-repeatability/specialheaders/repeatability/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py b/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py +++ b/packages/typespec-python/test/generated/special-words/specialwords/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py b/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-array/typetest/array/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-dictionary/typetest/dictionary/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-enum-extensible/typetest/enum/extensible/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-enum-fixed/typetest/enum/fixed/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-empty/typetest/model/empty/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/typetest-model-nesteddiscriminator/typetest/model/nesteddiscriminator/_model_base.py b/packages/typespec-python/test/generated/typetest-model-nesteddiscriminator/typetest/model/nesteddiscriminator/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/typetest-model-nesteddiscriminator/typetest/model/nesteddiscriminator/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-nesteddiscriminator/typetest/model/nesteddiscriminator/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/typetest-model-notdiscriminated/typetest/model/notdiscriminated/_model_base.py b/packages/typespec-python/test/generated/typetest-model-notdiscriminated/typetest/model/notdiscriminated/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/typetest-model-notdiscriminated/typetest/model/notdiscriminated/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-notdiscriminated/typetest/model/notdiscriminated/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/typetest-model-singlediscriminator/typetest/model/singlediscriminator/_model_base.py b/packages/typespec-python/test/generated/typetest-model-singlediscriminator/typetest/model/singlediscriminator/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/typetest-model-singlediscriminator/typetest/model/singlediscriminator/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-singlediscriminator/typetest/model/singlediscriminator/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-usage/typetest/model/usage/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-model-visibility/typetest/model/visibility/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-nullable/typetest/property/nullable/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-optional/typetest/property/optional/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-property-valuetypes/typetest/property/valuetypes/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, diff --git a/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py b/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py index 50b93b4941d..bbb1857dd64 100644 --- a/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py +++ b/packages/typespec-python/test/generated/typetest-union/typetest/union/_model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -563,7 +562,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None, From 25cf245c15201a6de59e1edfdea0f0d7b5314f45 Mon Sep 17 00:00:00 2001 From: tadelesh Date: Fri, 11 Aug 2023 11:28:49 +0800 Subject: [PATCH 13/13] update unittests --- .../typespec-python/test/unittests/generated/model_base.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/typespec-python/test/unittests/generated/model_base.py b/packages/typespec-python/test/unittests/generated/model_base.py index e9c4d0289ba..17c08a23b49 100644 --- a/packages/typespec-python/test/unittests/generated/model_base.py +++ b/packages/typespec-python/test/unittests/generated/model_base.py @@ -137,8 +137,7 @@ def default(self, o): # pylint: disable=too-many-return-statements if self.exclude_readonly: readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] return {k: v for k, v in o.items() if k not in readonly_props} - else: - return dict(o.items()) + return dict(o.items()) if isinstance(o, (bytes, bytearray)): return base64.b64encode(o).decode() if isinstance(o, _Null): @@ -577,7 +576,7 @@ def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v -def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements +def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915, R0912 annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None,