Skip to content

Commit ac7c3e8

Browse files
committed
Merge branch 'main' into fix/deserialize-object
2 parents ad700b2 + 88655dc commit ac7c3e8

File tree

5 files changed

+68
-15
lines changed

5 files changed

+68
-15
lines changed

src/ansys/openapi/common/__init__.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
__version__ = metadata.version("ansys-openapi-common")
66

77
from ._api_client import ApiClient
8-
from ._base import ApiBase, ApiClientBase, ModelBase
8+
from ._base import ApiBase, ApiClientBase, ModelBase, Unset, Unset_Type
99
from ._exceptions import (
1010
ApiConnectionException,
1111
ApiException,
@@ -28,4 +28,6 @@
2828
"ApiClientBase",
2929
"ModelBase",
3030
"UndefinedObjectWarning",
31+
"Unset",
32+
"Unset_Type",
3133
]

src/ansys/openapi/common/_api_client.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
warnings.simplefilter("ignore", category=DeprecationWarning)
3030
from dateutil.parser import parse
3131

32-
from ._base import ApiClientBase, DeserializedType, ModelBase, PrimitiveType, SerializedType
32+
from ._base import ApiClientBase, DeserializedType, ModelBase, PrimitiveType, SerializedType, Unset
3333
from ._exceptions import ApiException, UndefinedObjectWarning
3434
from ._util import SessionConfiguration, handle_response
3535

@@ -137,7 +137,7 @@ def __call_api(
137137
collection_formats: Optional[Dict[str, str]] = None,
138138
_preload_content: bool = True,
139139
_request_timeout: Union[float, Tuple[float, float], None] = None,
140-
response_type_map: Optional[Dict[int, Union[str, None]]] = None,
140+
response_type_map: Optional[Mapping[int, Union[str, None]]] = None,
141141
) -> Union[requests.Response, DeserializedType, None]:
142142
# header parameters
143143
header_params = header_params or {}
@@ -276,7 +276,7 @@ def sanitize_for_serialization(self, obj: Any) -> Any:
276276
obj_dict = {
277277
obj.attribute_map[attr]: getattr(obj, attr)
278278
for attr in obj.swagger_types
279-
if getattr(obj, attr) is not None
279+
if getattr(obj, attr) is not Unset
280280
}
281281

282282
return {key: self.sanitize_for_serialization(val) for key, val in obj_dict.items()}
@@ -411,7 +411,7 @@ def call_api(
411411
collection_formats: Optional[Dict[str, str]] = None,
412412
_preload_content: bool = True,
413413
_request_timeout: Union[float, Tuple[float, float], None] = None,
414-
response_type_map: Optional[Dict[int, Union[str, None]]] = None,
414+
response_type_map: Optional[Mapping[int, Union[str, None]]] = None,
415415
) -> Union[requests.Response, DeserializedType, None]:
416416
"""Make the HTTP request and return the deserialized data.
417417
@@ -868,7 +868,7 @@ def __deserialize_model(
868868
if key not in klass.swagger_types:
869869
instance[key] = value
870870
try:
871-
klass_name = instance.get_real_child_model(data)
871+
klass_name = instance.get_real_child_model(data) # type: ignore[arg-type]
872872
if klass_name:
873873
instance = self.__deserialize(data, klass_name) # type: ignore[assignment]
874874
except NotImplementedError:

src/ansys/openapi/common/_base/_types.py

+15-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import datetime
33
from enum import Enum
44
import pprint
5-
from typing import Any, Dict, List, Optional, Tuple, Union
5+
from typing import Any, Dict, List, Literal, Mapping, Optional, Tuple, Union
66

77
import requests
88

@@ -75,7 +75,7 @@ def to_str(self) -> str:
7575
"""
7676
return pprint.pformat(self.to_dict())
7777

78-
def get_real_child_model(self, data: Union[Dict, str]) -> str:
78+
def get_real_child_model(self, data: Dict[str, str]) -> str:
7979
"""Classes with discriminators will override this method and may change the method signature."""
8080
raise NotImplementedError()
8181

@@ -110,12 +110,23 @@ def call_api(
110110
header_params: Union[Dict[str, Union[str, int]], None] = None,
111111
body: Optional[DeserializedType] = None,
112112
post_params: Optional[List[Tuple[str, Union[str, bytes]]]] = None,
113-
files: Optional[Dict[str, str]] = None,
113+
files: Optional[Mapping[str, str]] = None,
114114
response_type: Optional[str] = None,
115115
_return_http_data_only: Optional[bool] = None,
116116
collection_formats: Optional[Dict[str, str]] = None,
117117
_preload_content: bool = True,
118118
_request_timeout: Union[float, Tuple[float, float], None] = None,
119-
response_type_map: Optional[Dict[int, Union[str, None]]] = None,
119+
response_type_map: Optional[Mapping[int, Union[str, None]]] = None,
120120
) -> Union[requests.Response, DeserializedType, None]:
121121
"""Provide method signature for calling the API."""
122+
123+
124+
class _Unset:
125+
@staticmethod
126+
def __bool__() -> Literal[False]:
127+
return False
128+
129+
130+
Unset_Type = _Unset
131+
Unset = _Unset()
132+
"""Magic value to indicate a value has not been set."""

tests/models/example_model.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from ansys.openapi.common import ModelBase
1+
from ansys.openapi.common import ModelBase, Unset
22

33

44
class ExampleModel(ModelBase):
@@ -31,15 +31,17 @@ class ExampleModel(ModelBase):
3131

3232
def __init__(
3333
self,
34-
string_property=None,
35-
int_property=None,
36-
bool_property=None,
37-
list_property=None,
34+
string_property=Unset,
35+
int_property=Unset,
36+
bool_property=Unset,
37+
list_property=Unset,
3838
): # noqa: E501
3939
self._string_property = None
4040
self._int_property = None
4141
self._bool_property = None
4242
self._list_property = None
43+
self._nullable_property = None
44+
self._optional_property = None
4345
self.discriminator = None
4446
if string_property is not None:
4547
self._string_property = string_property

tests/test_api_client.py

+38
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,44 @@ def test_serialize_model(self):
191191
serialized_model = self._client.sanitize_for_serialization(model_instance)
192192
assert serialized_model == model_dict
193193

194+
def test_serialize_model_null_values(self):
195+
from . import models
196+
197+
self._client.setup_client(models)
198+
model_instance = models.ExampleModel("foo", None, False, None)
199+
model_dict = {
200+
"Boolean": False,
201+
"Integer": None,
202+
"ListOfStrings": None,
203+
"String": "foo",
204+
}
205+
serialized_model = self._client.sanitize_for_serialization(model_instance)
206+
assert serialized_model == model_dict
207+
208+
def test_serialize_model_unset_values(self):
209+
from . import models
210+
211+
self._client.setup_client(models)
212+
model_instance = models.ExampleModel(int_property=3, list_property=["It's", "a", "list"])
213+
model_dict = {
214+
"Integer": 3,
215+
"ListOfStrings": ["It's", "a", "list"],
216+
}
217+
serialized_model = self._client.sanitize_for_serialization(model_instance)
218+
assert serialized_model == model_dict
219+
220+
def test_serialize_model_set_unset_and_null_values(self):
221+
from . import models
222+
223+
self._client.setup_client(models)
224+
model_instance = models.ExampleModel(int_property=None, list_property=["It's", "a", "list"])
225+
model_dict = {
226+
"Integer": None,
227+
"ListOfStrings": ["It's", "a", "list"],
228+
}
229+
serialized_model = self._client.sanitize_for_serialization(model_instance)
230+
assert serialized_model == model_dict
231+
194232
def test_serialize_enum_model(self):
195233
from . import models
196234

0 commit comments

Comments
 (0)