-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
06d66a9
commit 99190aa
Showing
10 changed files
with
506 additions
and
236 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
__all__ = ["OrderedSetSerializer"] | ||
|
||
|
||
from typing import Generic, TypeVar | ||
|
||
from ordered_set import OrderedSet | ||
|
||
from .._base import Serializer | ||
from .._result import DeserializationFailure, DeserializationResult, DeserializationSuccess | ||
from .._stable_set import StableSet | ||
|
||
Element = TypeVar("Element") | ||
|
||
|
||
class OrderedSetSerializer(Generic[Element], Serializer[OrderedSet[Element]]): | ||
def __init__(self, element_serializer: Serializer[Element]): | ||
self.element_serializer = element_serializer | ||
|
||
def from_data(self, data) -> DeserializationResult[OrderedSet[Element]]: | ||
# Return early if the data isn't even a list | ||
if not isinstance(data, list): | ||
return DeserializationFailure(f"Not a valid list: {data!r}") | ||
|
||
# Validate values | ||
errors = {} | ||
values = OrderedSet() | ||
for i, value in enumerate(data): | ||
value_or_error = self.element_serializer.from_data(value) | ||
if isinstance(value_or_error, DeserializationFailure): | ||
errors[str(i)] = value_or_error.error | ||
elif value_or_error.value in values: | ||
errors[str(i)] = ( | ||
f"Duplicated value found: {value_or_error.value!r}. " | ||
"Expected a list of unique values." | ||
) | ||
else: | ||
values.add(value_or_error.value) | ||
|
||
if len(errors) > 0: | ||
return DeserializationFailure(errors) | ||
else: | ||
return DeserializationSuccess(values) | ||
|
||
def to_data(self, value: OrderedSet[Element]): | ||
if not isinstance(value, OrderedSet): | ||
raise ValueError(f"Not an OrderedSet: {value!r}") | ||
|
||
return [self.element_serializer.to_data(item) for item in value] | ||
|
||
def collect_openapi_models( | ||
self, parent_models: StableSet[Serializer] | ||
) -> StableSet[Serializer]: | ||
return self.element_serializer.collect_openapi_models(parent_models) | ||
|
||
def to_openapi_schema(self, refs: dict[Serializer, str], force: bool = False): | ||
return {"type": "array", "items": self.element_serializer.to_openapi_schema(refs)} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
__all__ = ["SetSerializer"] | ||
|
||
|
||
from typing import Generic, TypeVar | ||
|
||
from .._base import Serializer | ||
from .._result import DeserializationFailure, DeserializationResult, DeserializationSuccess | ||
from .._stable_set import StableSet | ||
|
||
Element = TypeVar("Element") | ||
|
||
|
||
class SetSerializer(Generic[Element], Serializer[set[Element]]): | ||
def __init__(self, element_serializer: Serializer[Element]): | ||
self.element_serializer = element_serializer | ||
|
||
def from_data(self, data) -> DeserializationResult[set[Element]]: | ||
# Return early if the data isn't even a list | ||
if not isinstance(data, list): | ||
return DeserializationFailure(f"Not a valid list: {data!r}") | ||
|
||
# Validate values | ||
errors = {} | ||
values = set() | ||
for i, value in enumerate(data): | ||
value_or_error = self.element_serializer.from_data(value) | ||
if isinstance(value_or_error, DeserializationFailure): | ||
errors[str(i)] = value_or_error.error | ||
elif value_or_error.value in values: | ||
errors[str(i)] = ( | ||
f"Duplicated value found: {value_or_error.value!r}. " | ||
"Expected a list of unique values." | ||
) | ||
else: | ||
values.add(value_or_error.value) | ||
|
||
if len(errors) > 0: | ||
return DeserializationFailure(errors) | ||
else: | ||
return DeserializationSuccess(values) | ||
|
||
def to_data(self, value: set[Element]): | ||
if not isinstance(value, set): | ||
raise ValueError(f"Not a set: {value!r}") | ||
|
||
return [self.element_serializer.to_data(item) for item in value] | ||
|
||
def collect_openapi_models( | ||
self, parent_models: StableSet[Serializer] | ||
) -> StableSet[Serializer]: | ||
return self.element_serializer.collect_openapi_models(parent_models) | ||
|
||
def to_openapi_schema(self, refs: dict[Serializer, str], force: bool = False): | ||
return {"type": "array", "items": self.element_serializer.to_openapi_schema(refs)} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import pytest | ||
|
||
try: | ||
from ordered_set import OrderedSet | ||
except ImportError: | ||
pytest.skip("ordered-set not available", allow_module_level=True) | ||
|
||
from serialite import ( | ||
DeserializationFailure, | ||
DeserializationSuccess, | ||
FloatSerializer, | ||
OrderedSetSerializer, | ||
) | ||
|
||
ordered_set_serializer = OrderedSetSerializer(FloatSerializer()) | ||
|
||
|
||
def test_valid_inputs(): | ||
data = [12.3, 15.5, 16.0] | ||
value = OrderedSet([12.3, 15.5, 16.0]) | ||
|
||
assert ordered_set_serializer.from_data(data) == DeserializationSuccess(value) | ||
assert ordered_set_serializer.to_data(value) == data | ||
|
||
|
||
def test_from_data_failure_top_level(): | ||
data = 12.5 | ||
assert ordered_set_serializer.from_data(data) == DeserializationFailure( | ||
"Not a valid list: 12.5" | ||
) | ||
|
||
|
||
def test_from_data_failure_element(): | ||
data = ["str1", 15.5, "str2"] | ||
actual = ordered_set_serializer.from_data(data) | ||
expected_msg = {"0": "Not a valid float: 'str1'", "2": "Not a valid float: 'str2'"} | ||
assert actual == DeserializationFailure(expected_msg) | ||
|
||
|
||
def test_from_data_failure_uniqueness(): | ||
data = [12.3, 15.5, 16.0, 12.3] | ||
actual = ordered_set_serializer.from_data(data) | ||
expected_msg = {"3": "Duplicated value found: 12.3. Expected a list of unique values."} | ||
assert actual == DeserializationFailure(expected_msg) | ||
|
||
|
||
def test_to_data_failure_top_level(): | ||
with pytest.raises(ValueError): | ||
_ = ordered_set_serializer.to_data(12.5) | ||
|
||
|
||
def test_to_data_failure_element(): | ||
with pytest.raises(ValueError): | ||
_ = ordered_set_serializer.to_data(OrderedSet([12.5, "a"])) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import pytest | ||
|
||
from serialite import ( | ||
DeserializationFailure, | ||
DeserializationSuccess, | ||
FloatSerializer, | ||
SetSerializer, | ||
) | ||
|
||
set_serializer = SetSerializer(FloatSerializer()) | ||
|
||
|
||
def test_valid_inputs(): | ||
data = [12.3, 15.5, 16.0] | ||
value = {12.3, 15.5, 16.0} | ||
|
||
assert set_serializer.from_data(data) == DeserializationSuccess(value) | ||
assert sorted(set_serializer.to_data(value)) == sorted(data) | ||
|
||
|
||
def test_from_data_failure_top_level(): | ||
data = 12.5 | ||
assert set_serializer.from_data(data) == DeserializationFailure("Not a valid list: 12.5") | ||
|
||
|
||
def test_from_data_failure_element(): | ||
data = ["str1", 15.5, "str2"] | ||
actual = set_serializer.from_data(data) | ||
expected_msg = {"0": "Not a valid float: 'str1'", "2": "Not a valid float: 'str2'"} | ||
assert actual == DeserializationFailure(expected_msg) | ||
|
||
|
||
def test_from_data_failure_uniqueness(): | ||
data = [12.3, 15.5, 16.0, 12.3] | ||
actual = set_serializer.from_data(data) | ||
expected_msg = {"3": "Duplicated value found: 12.3. Expected a list of unique values."} | ||
assert actual == DeserializationFailure(expected_msg) | ||
|
||
|
||
def test_to_data_failure_top_level(): | ||
with pytest.raises(ValueError): | ||
_ = set_serializer.to_data(12.5) | ||
|
||
|
||
def test_to_data_failure_element(): | ||
with pytest.raises(ValueError): | ||
_ = set_serializer.to_data({12.5, "a"}) |