Skip to content

Commit e38cf4e

Browse files
authored
♻️Fix settings library tests (#6605)
1 parent 39aed6a commit e38cf4e

File tree

79 files changed

+192
-143
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+192
-143
lines changed

packages/common-library/requirements/_base.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@
33
#
44
--constraint ../../../requirements/constraints.txt
55

6+
orjson
67
pydantic
8+
pydantic-extra-types

packages/common-library/requirements/_base.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
annotated-types==0.7.0
22
# via pydantic
3+
orjson==3.10.10
4+
# via
5+
# -c requirements/../../../requirements/constraints.txt
6+
# -r requirements/_base.in
37
pydantic==2.9.2
48
# via
59
# -c requirements/../../../requirements/constraints.txt
610
# -r requirements/_base.in
11+
# pydantic-extra-types
712
pydantic-core==2.23.4
813
# via pydantic
14+
pydantic-extra-types==2.9.0
15+
# via -r requirements/_base.in
916
typing-extensions==4.12.2
1017
# via
1118
# pydantic
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# pylint: disable=redefined-outer-name
2+
# pylint: disable=unused-argument
3+
# pylint: disable=unused-variable
4+
5+
import json
6+
from copy import deepcopy
7+
from typing import Annotated, Any, TypeAlias
8+
from uuid import uuid4
9+
10+
import pytest
11+
from common_library.json_serialization import (
12+
JsonNamespace,
13+
SeparatorTuple,
14+
json_dumps,
15+
json_loads,
16+
)
17+
from faker import Faker
18+
from pydantic import Field, TypeAdapter
19+
from pydantic.json import pydantic_encoder
20+
21+
22+
@pytest.fixture
23+
def fake_data_dict(faker: Faker) -> dict[str, Any]:
24+
data = {
25+
"uuid_as_UUID": faker.uuid4(cast_to=None),
26+
"uuid_as_str": faker.uuid4(),
27+
"int": faker.pyint(),
28+
"float": faker.pyfloat(),
29+
"str": faker.pystr(),
30+
"dict": faker.pydict(),
31+
"list": faker.pylist(),
32+
}
33+
data["object"] = deepcopy(data)
34+
return data
35+
36+
37+
def test_json_dump_variants():
38+
39+
uuid_obj = uuid4()
40+
41+
with pytest.raises(TypeError) as exc_info:
42+
json.dumps(uuid_obj)
43+
44+
assert str(exc_info.value) == "Object of type UUID is not JSON serializable"
45+
46+
assert json_dumps(uuid_obj) == json.dumps(str(uuid_obj))
47+
48+
49+
def test_serialized_non_str_dict_keys():
50+
# tests orjson.OPT_NON_STR_KEYS option
51+
52+
# if a dict has a key of a type other than str it will NOT raise
53+
json_dumps({1: "foo"})
54+
55+
56+
ConstrainedFloat: TypeAlias = Annotated[float, Field(ge=0.0, le=1.0)]
57+
58+
59+
def test_serialized_constraint_floats():
60+
# test extension of ENCODERS_BY_TYPE used in pydantic_encoder
61+
62+
json_dumps({"value": 1.0})
63+
64+
# TypeError: Type is not JSON serializable: ProgressPercent
65+
json_dumps({"value": TypeAdapter(ConstrainedFloat).validate_python(1.0)})
66+
67+
68+
def _expected_json_dumps(obj: Any, default=pydantic_encoder, **json_dumps_kwargs):
69+
if "indent" not in json_dumps_kwargs:
70+
json_dumps_kwargs.setdefault(
71+
"separators",
72+
SeparatorTuple(item_separator=",", key_separator=":"), # compact separators
73+
)
74+
return json.dumps(obj, default=default, **json_dumps_kwargs)
75+
76+
77+
@pytest.mark.parametrize(
78+
"kwargs",
79+
[
80+
pytest.param({}, id="no-kw"),
81+
pytest.param({"sort_keys": True}, id="sort_keys-kw"),
82+
pytest.param(
83+
{"separators": (",", ":")}, id="default_separators-kw"
84+
), # NOTE: e.g. engineio.packet has `self.json.dumps(self.data, separators=(',', ':'))`
85+
pytest.param(
86+
{"indent": 2}, id="indent-kw"
87+
), # NOTE: only one-to-one with indent=2
88+
],
89+
)
90+
def test_compatiblity_with_json_interface(
91+
fake_data_dict: dict[str, Any], kwargs: dict[str, Any]
92+
):
93+
orjson_dump = JsonNamespace.dumps(fake_data_dict, **kwargs)
94+
json_dump = _expected_json_dumps(fake_data_dict, **kwargs)
95+
96+
# NOTE: cannot compare dumps directly because orjson compacts it more
97+
assert json_loads(orjson_dump) == json_loads(json_dump)

packages/models-library/src/models_library/service_settings_labels.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from pathlib import Path
66
from typing import Any, Literal, TypeAlias
77

8+
from common_library.json_serialization import json_dumps
89
from pydantic import (
910
BaseModel,
1011
ByteSize,
@@ -23,7 +24,6 @@
2324
from .generics import ListModel
2425
from .service_settings_nat_rule import NATRule
2526
from .services_resources import DEFAULT_SINGLE_SERVICE_NAME
26-
from .utils.json_serialization import json_dumps
2727

2828
_BaseConfig = ConfigDict(
2929
extra="forbid", arbitrary_types_allowed=True, ignored_types=(cached_property,)

packages/models-library/src/models_library/utils/_original_fastapi_encoders.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from types import GeneratorType
1111
from typing import Any, Callable, Union
1212

13-
from models_library.utils.json_serialization import ENCODERS_BY_TYPE
13+
from common_library.json_serialization import ENCODERS_BY_TYPE
1414
from pydantic import BaseModel
1515
from pydantic_core import PydanticUndefined, PydanticUndefinedType
1616
from typing_extensions import Annotated, Doc

packages/models-library/src/models_library/utils/labels_annotations.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from json.decoder import JSONDecodeError
99
from typing import Any, TypeAlias
1010

11-
from .json_serialization import json_dumps
11+
from common_library.json_serialization import json_dumps
1212

1313
LabelsAnnotationsDict: TypeAlias = dict[str, str]
1414

packages/models-library/src/models_library/utils/specs_substitution.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
from typing import Any, NamedTuple, TypeAlias, cast
22

33
from common_library.errors_classes import OsparcErrorMixin
4-
4+
from common_library.json_serialization import json_dumps, json_loads
55
from pydantic import StrictBool, StrictFloat, StrictInt
66

7-
from .json_serialization import json_dumps, json_loads
87
from .string_substitution import (
98
SubstitutionsDict,
109
TextTemplate,

packages/models-library/tests/test_utils_json_serialization.py

Lines changed: 1 addition & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -3,43 +3,14 @@
33
# pylint: disable=unused-variable
44

55

6-
import json
76
from copy import deepcopy
87
from typing import Any
98
from uuid import uuid4
109

1110
import pytest
11+
from common_library.json_serialization import json_dumps, json_loads
1212
from faker import Faker
13-
from models_library.api_schemas_long_running_tasks.base import ProgressPercent
1413
from models_library.utils.fastapi_encoders import jsonable_encoder
15-
from models_library.utils.json_serialization import (
16-
JsonNamespace,
17-
SeparatorTuple,
18-
json_dumps,
19-
json_loads,
20-
)
21-
from pydantic.json import pydantic_encoder
22-
23-
24-
def _expected_json_dumps(obj: Any, default=pydantic_encoder, **json_dumps_kwargs):
25-
if "indent" not in json_dumps_kwargs:
26-
json_dumps_kwargs.setdefault(
27-
"separators",
28-
SeparatorTuple(item_separator=",", key_separator=":"), # compact separators
29-
)
30-
return json.dumps(obj, default=default, **json_dumps_kwargs)
31-
32-
33-
def test_json_dump_variants():
34-
35-
uuid_obj = uuid4()
36-
37-
with pytest.raises(TypeError) as exc_info:
38-
json.dumps(uuid_obj)
39-
40-
assert str(exc_info.value) == "Object of type UUID is not JSON serializable"
41-
42-
assert json_dumps(uuid_obj) == json.dumps(str(uuid_obj))
4314

4415

4516
@pytest.fixture
@@ -75,42 +46,3 @@ def test_serialization_of_nested_dicts(fake_data_dict: dict[str, Any]):
7546

7647
dump = json_dumps(obj)
7748
assert json_loads(dump) == jsonable_encoder(obj)
78-
79-
80-
@pytest.mark.parametrize(
81-
"kwargs",
82-
[
83-
pytest.param({}, id="no-kw"),
84-
pytest.param({"sort_keys": True}, id="sort_keys-kw"),
85-
pytest.param(
86-
{"separators": (",", ":")}, id="default_separators-kw"
87-
), # NOTE: e.g. engineio.packet has `self.json.dumps(self.data, separators=(',', ':'))`
88-
pytest.param(
89-
{"indent": 2}, id="indent-kw"
90-
), # NOTE: only one-to-one with indent=2
91-
],
92-
)
93-
def test_compatiblity_with_json_interface(
94-
fake_data_dict: dict[str, Any], kwargs: dict[str, Any]
95-
):
96-
orjson_dump = JsonNamespace.dumps(fake_data_dict, **kwargs)
97-
json_dump = _expected_json_dumps(fake_data_dict, **kwargs)
98-
99-
# NOTE: cannot compare dumps directly because orjson compacts it more
100-
assert json_loads(orjson_dump) == json_loads(json_dump)
101-
102-
103-
def test_serialized_non_str_dict_keys():
104-
# tests orjson.OPT_NON_STR_KEYS option
105-
106-
# if a dict has a key of a type other than str it will NOT raise
107-
json_dumps({1: "foo"})
108-
109-
110-
def test_serialized_constraint_floats():
111-
# test extension of ENCODERS_BY_TYPE used in pydantic_encoder
112-
113-
json_dumps({"value": 1.0})
114-
115-
# TypeError: Type is not JSON serializable: ProgressPercent
116-
json_dumps({"value": ProgressPercent(1.0)})

packages/pytest-simcore/src/pytest_simcore/helpers/aws_ec2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import base64
22
from collections.abc import Sequence
33

4+
from common_library.json_serialization import json_dumps
45
from models_library.docker import DockerGenericTag
5-
from models_library.utils.json_serialization import json_dumps
66
from types_aiobotocore_ec2 import EC2Client
77
from types_aiobotocore_ec2.literals import InstanceStateNameType, InstanceTypeType
88
from types_aiobotocore_ec2.type_defs import FilterTypeDef, InstanceTypeDef, TagTypeDef

0 commit comments

Comments
 (0)