Skip to content

Commit

Permalink
Issue #280 #281
Browse files Browse the repository at this point in the history
  • Loading branch information
loyada committed Dec 9, 2023
1 parent 8ae1299 commit 8e50b02
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 11 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
url="http://github.com/loyada/typedpy",
download_url="https://github.com/loyada/typedpy/archive/v2.27.1.tar.gz",
keywords=["testing", "type-safe", "strict", "schema", "validation"],
version="2.27.1",
version="2.27.2",
)

# coverage run --source=typedpy/ setup.py test
Expand Down
41 changes: 38 additions & 3 deletions tests/test_deserialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ class Foo(Structure):
)


def test_single_int_deserialization():
def test_single_int_deserialization(compact_serialization):
class Foo(Structure):
i = Integer
_additionalProperties = False
Expand All @@ -459,7 +459,7 @@ class Foo(Structure):
assert example.i == 5


def test_single_int_deserialization1():
def test_single_int_deserialization1(compact_serialization):
class Foo(Structure):
i = Integer
_additional_properties = False
Expand All @@ -470,7 +470,7 @@ class Foo(Structure):
assert example.i == 5


def test_single_array_deserialization():
def test_single_array_deserialization(compact_serialization):
class Foo(Structure):
arr = Array[String]
_additionalProperties = False
Expand Down Expand Up @@ -1500,3 +1500,38 @@ class Foo(Structure):
assert deserialize({"b": 5}) == Foo(a=5)
with raises(TypeError):
deserialize({"a": 5})


def test_additional_properties_turned_off_err(additional_props_default_is_false):
class Foo(Structure):
a: int
b: int
_required = []

with raises(TypeError) as excinfo:
Deserializer(Foo).deserialize({"c": 1, "a": 2})

assert (
"Foo: got an unexpected keyword argument 'c'"
in str(excinfo.value)
)


def test_smart_compact_deserialization_is_turned_off_by_default():
class Foo(Structure):
a: list[int]
_additional_properties = False

with raises(TypeError) as excinfo:
Deserializer(Foo).deserialize([2, 3])
assert (
"Expected a dictionary; Got [2, 3]"
in str(excinfo.value)
)

def test_smart_compact_deserialization_is_turned_on(compact_serialization):
class Foo(Structure):
a: list[int]
_additional_properties = False

assert Deserializer(Foo).deserialize([2, 3]) == Foo(a=[2,3])
4 changes: 3 additions & 1 deletion typedpy/serialization/fast_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ def serializer(self):
)

return (
filtered_res if serialize_none else {k: v for (k, v) in filtered_res.items() if v is not None}
filtered_res
if serialize_none
else {k: v for (k, v) in filtered_res.items() if v is not None}
)

cls.serialize = serializer
Expand Down
4 changes: 1 addition & 3 deletions typedpy/serialization/mappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,6 @@ def _try_int(x):
return x




def _apply_mapper(
latest_mapper, key, previous_mapper, for_serialization, is_self=False
):
Expand All @@ -99,7 +97,7 @@ def _apply_mapper(
if latest_mapper == mappers.TO_LOWERCASE:
return val.upper()
if latest_mapper == mappers.CONFIGURATION:
return FunctionCall(func= _try_int)
return FunctionCall(func=_try_int)
latest_mapper_val = latest_mapper.get(val, val)
if isinstance(latest_mapper_val, (FunctionCall,)):
args = (
Expand Down
7 changes: 6 additions & 1 deletion typedpy/serialization/serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -806,7 +806,12 @@ class reference field. Users are not supposed to use this argument.
additional_props = props.get(
ADDITIONAL_PROPERTIES, TypedPyDefaults.additional_properties_default
)
if len(fields) == 1 and required == fields and additional_props is False:
if (
len(fields) == 1
and required == fields
and additional_props is False
and TypedPyDefaults.compact_serialization_default
):
field_name = fields[0]
return cls(
deserialize_single_field(
Expand Down
14 changes: 12 additions & 2 deletions typedpy/serialization/serialization_wrappers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from typedpy.commons import wrap_val
from typedpy.structures import Structure, TypedPyDefaults
from typedpy.structures import Structure, TypedPyDefaults, ADDITIONAL_PROPERTIES
from typedpy.fields import StructureClass, Map, String, OneOf, Boolean, FunctionCall
from .serialization import deserialize_structure, serialize

Expand Down Expand Up @@ -87,12 +87,22 @@ def __validate__(self):
def deserialize(
self, input_data, *, keep_undefined=None, direct_trusted_mapping=False
):
additional_props_allowed = getattr(
self.target_class,
ADDITIONAL_PROPERTIES,
TypedPyDefaults.additional_properties_default,
)
adjusted_keep_undefined = (
keep_undefined
if keep_undefined is not None or additional_props_allowed
else True
)
return deserialize_structure(
self.target_class,
input_data,
mapper=self.mapper,
use_strict_mapping=self.use_strict_mapping,
keep_undefined=keep_undefined,
keep_undefined=adjusted_keep_undefined,
camel_case_convert=self.camel_case_convert,
direct_trusted_mapping=direct_trusted_mapping,
)
Expand Down

0 comments on commit 8e50b02

Please sign in to comment.