Skip to content

Commit

Permalink
Fixed two bugs with JSON model and dynamically_convert_elements_to_mo…
Browse files Browse the repository at this point in the history
…dels=True
  • Loading branch information
sveinugu committed Aug 13, 2024
1 parent 1bac796 commit cbcc52d
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 10 deletions.
11 changes: 9 additions & 2 deletions src/omnipy/data/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
from omnipy.api.typedefs import TypeForm
from omnipy.data.data_class_creator import DataClassBase, DataClassBaseMeta
from omnipy.data.helpers import get_special_methods_info_dict, MethodInfo, YesNoMaybe
from omnipy.util.contexts import (AttribHolder,
from omnipy.util.contexts import (hold_and_reset_prev_attrib_value_context,
ignore_error,
LastErrorHolder,
nothing,
Expand Down Expand Up @@ -1106,7 +1106,12 @@ def _call_method_with_unconverted_args_first(
**kwargs: object,
):
try:
ret = method(*args, **kwargs)
with hold_and_reset_prev_attrib_value_context(
self.config,
'dynamically_convert_elements_to_models',
):
self.config.dynamically_convert_elements_to_models = False
ret = method(*args, **kwargs)
except TypeError as type_exc:
try:
ret = self._call_method_with_model_converted_args(method, *args, **kwargs)
Expand Down Expand Up @@ -1188,6 +1193,8 @@ def _convert_to_model_if_reasonable( # noqa: C901

if level_up:
inner_type_args = get_args(inner_type_to_check)
if len(inner_type_args) == 0:
inner_type_args = (inner_type_to_check,)
if inner_type_args:
for level_up_type_to_check in all_type_variants(
inner_type_args[level_up_arg_idx]):
Expand Down
43 changes: 35 additions & 8 deletions tests/modules/json/test_json_models.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
from dataclasses import fields
import os
from textwrap import dedent
from typing import TypeAlias
from typing import Annotated, TypeAlias

from pydantic import ValidationError
import pytest
import pytest_cases as pc

from omnipy.api.protocols.public.hub import IsRuntime
from omnipy.modules.json.models import (_JsonAnyDictM,
_JsonAnyListM,
_JsonDictM,
Expand All @@ -23,6 +24,7 @@
JsonScalarModel)
from omnipy.modules.json.typedefs import JsonScalar

from ...helpers.functions import assert_model_or_val
from ..helpers.classes import CaseInfo


Expand Down Expand Up @@ -131,15 +133,40 @@ def test_error_list_of_single_dict_with_two_elements():

# TODO: Write tests for misc model operations relevant for JSON data. Try to avoid overlap with
# with test_model.
def test_json_model_operations():
a = JsonDictModel({'a': 1, 'b': 2, 'c': 3})
a['c'] = 3
@pytest.mark.parametrize('dyn_convert', [False, True])
def test_json_model_operations(
runtime: Annotated[IsRuntime, pytest.fixture],
dyn_convert: bool,
):
runtime.config.data.dynamically_convert_elements_to_models = dyn_convert

b = _JsonScalarM(1)
assert (b + 1).contents == 2
a = JsonListModel([1, 2, 3])
assert_model_or_val(dyn_convert, a[0], int, 1)

c = JsonScalarModel(1)
assert (c + 1).contents == 2
b = JsonModel([1, 2, 3])
assert_model_or_val(dyn_convert, b[0], int, 1)

c = JsonDictModel({'a': 1, 'b': 2, 'c': 3})
assert_model_or_val(dyn_convert, c['c'], int, 3)

c |= JsonDictModel({'b': 4, 'd': 5})
assert_model_or_val(dyn_convert, c['b'], int, 4)
assert_model_or_val(dyn_convert, c['c'], int, 3)
assert_model_or_val(dyn_convert, c['d'], int, 5)

d = JsonModel({'a': 1, 'b': 2, 'c': 3})
assert_model_or_val(dyn_convert, d['c'], int, 3)

d |= JsonModel({'b': 4, 'd': 5})
assert_model_or_val(dyn_convert, c['b'], int, 4)
assert_model_or_val(dyn_convert, c['c'], int, 3)
assert_model_or_val(dyn_convert, c['d'], int, 5)

e = _JsonScalarM(1)
assert (e + 1).contents == 2

f = JsonScalarModel(1)
assert (f + 1).contents == 2


def test_json_known_bug():
Expand Down

0 comments on commit cbcc52d

Please sign in to comment.