Skip to content

Commit

Permalink
added method that converts a spock class or iteratble of spock classe…
Browse files Browse the repository at this point in the history
…s to a dictionary
  • Loading branch information
ncilfone committed Apr 27, 2022
1 parent 2e041e2 commit 4fded54
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 2 deletions.
35 changes: 33 additions & 2 deletions spock/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,14 @@
from spock.backend.payload import AttrPayload
from spock.backend.saver import AttrSaver
from spock.backend.wrappers import Spockspace
from spock.exceptions import _SpockEvolveError
from spock.utils import _C, _T, check_payload_overwrite, deep_payload_update
from spock.exceptions import _SpockEvolveError, _SpockValueError
from spock.utils import (
_C,
_T,
_is_spock_instance,
check_payload_overwrite,
deep_payload_update,
)


class ConfigArgBuilder:
Expand Down Expand Up @@ -588,6 +594,31 @@ def spockspace_2_dict(self, payload: Spockspace) -> Dict:
"""
return self._saver_obj.dict_payload(payload)

def obj_2_dict(self, obj: Union[_C, List[_C], Tuple[_C, ...]]) -> Dict[str, Dict]:
"""Converts spock classes from a Spockspace into their dictionary representations
Args:
objs: single spock class or an iterable of spock classes
Returns:
dictionary where the class names are keys and the values are the dictionary representations
"""
if isinstance(obj, (List, Tuple)):
obj_dict = {}
for val in obj:
if not _is_spock_instance(val):
raise _SpockValueError(
f"Object is not a @spock decorated class object -- currently `{type(val)}`"
)
obj_dict.update({type(val).__name__: val})
elif _is_spock_instance(obj):
obj_dict = {type(obj).__name__: obj}
else:
raise _SpockValueError(
f"Object is not a @spock decorated class object -- currently `{type(obj)}`"
)
return self.spockspace_2_dict(Spockspace(**obj_dict))

def evolve(self, *args: _C) -> Spockspace:
"""Function that allows a user to evolve the underlying spock classes with instantiated spock objects
Expand Down
3 changes: 3 additions & 0 deletions tests/base/test_evolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,6 @@ def test_2_dict(self, arg_builder):
# Evolve the class
new_class = arg_builder.evolve(evolve_nested_stuff, evolve_type_config)
assert isinstance(arg_builder.spockspace_2_dict(new_class), dict) is True



44 changes: 44 additions & 0 deletions tests/base/test_spockspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from attr.exceptions import FrozenInstanceError

from spock.builder import ConfigArgBuilder
from spock.exceptions import _SpockValueError
from tests.base.attr_configs_test import *


Expand Down Expand Up @@ -35,6 +36,49 @@ def test_repr(self, monkeypatch, capsys):
assert ("NestedListStuff" in out) and "TypeConfig" in out


class TestToDict:
def test_2_dict(self, monkeypatch):
with monkeypatch.context() as m:
m.setattr(sys, "argv", ["", "--config", "./tests/conf/yaml/test.yaml"])
config = ConfigArgBuilder(
*all_configs,
desc="Test Builder",
)
configs = config.generate()
config_dict = config.spockspace_2_dict(configs)
assert isinstance(config_dict, dict) is True


class TestClassToDict:
def test_class_2_dict(self, monkeypatch):
with monkeypatch.context() as m:
m.setattr(sys, "argv", ["", "--config", "./tests/conf/yaml/test.yaml"])
config = ConfigArgBuilder(
*all_configs,
desc="Test Builder",
)
configs = config.generate()
config_dict = config.obj_2_dict(configs.TypeConfig)
assert isinstance(config_dict, dict) is True
assert isinstance(config_dict['TypeConfig'], dict) is True
configs_dicts = config.obj_2_dict((configs.TypeConfig, configs.NestedStuff))
assert isinstance(configs_dicts['TypeConfig'], dict) is True
assert isinstance(configs_dicts['NestedStuff'], dict) is True

def test_raise_incorrect_type(self, monkeypatch):
with monkeypatch.context() as m:
m.setattr(sys, "argv", ["", "--config", "./tests/conf/yaml/test.yaml"])
config = ConfigArgBuilder(
*all_configs,
desc="Test Builder",
)
configs = config.generate()
with pytest.raises(_SpockValueError):
config_dict = config.obj_2_dict("foo")
with pytest.raises(_SpockValueError):
config_dict = config.obj_2_dict(("foo", 10))


class TestFrozen:
"""Testing the frozen state of the spock config object"""

Expand Down

0 comments on commit 4fded54

Please sign in to comment.