Skip to content

Commit

Permalink
Merge 1fcbe93 into e9ddc98
Browse files Browse the repository at this point in the history
  • Loading branch information
ncilfone authored Jan 3, 2022
2 parents e9ddc98 + 1fcbe93 commit f5f1db1
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 5 deletions.
19 changes: 18 additions & 1 deletion spock/backend/field_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,24 @@ def handle_optional_attribute_value(
super().handle_optional_attribute_value(attr_space, builder_space)
if attr_space.field is not None:
list_item_spock_class = attr_space.field
builder_space.spock_space[list_item_spock_class.__name__] = attr_space.field
# Here we need to catch the possibility of repeated lists via coded defaults
if _is_spock_instance(attr_space.attribute.metadata["type"].__args__[0]):
spock_cls = attr_space.attribute.metadata["type"].__args__[0]
# Fall back to configs if present
if spock_cls.__name__ in builder_space.arguments:
attr_space.field = self._process_list(spock_cls, builder_space)
# Here we need to attempt to instantiate any class references that still exist
try:
attr_space.field = [val() if type(val) is type else val for val in attr_space.field]
except Exception as e:
raise SpockInstantiationError(
f"Spock class `{spock_cls.__name__}` could not be instantiated -- attrs message: {e}"
)
builder_space.spock_space[spock_cls.__name__] = attr_space.field
else:
builder_space.spock_space[
list_item_spock_class.__name__
] = attr_space.field

@staticmethod
def _process_list(spock_cls, builder_space: BuilderSpace):
Expand Down
2 changes: 1 addition & 1 deletion spock/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def _post_process_config_paths(payload):
"""
Transform path string into path object
"""
if "config" in payload:
if (payload is not None) and "config" in payload:
payload["config"] = [Path(c) for c in payload["config"]]

return payload
Expand Down
16 changes: 13 additions & 3 deletions tests/base/attr_configs_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ class NestedListStuff:
two: str


@spock
class NestedListStuffDef:
one: int
two: str


class ClassChoice(Enum):
class_nested_stuff = NestedStuff
class_nested_list_stuff = NestedListStuff
Expand Down Expand Up @@ -235,8 +241,12 @@ class TypeDefaultConfig:
nested_def: NestedStuff = NestedStuff
# Nested configuration with no config
nested_no_conf_def: NestedStuffDefault = NestedStuffDefault()
# Nested list configuration
nested_list_def: List[NestedListStuff] = NestedListStuff
# Nested list configuration -- defaults to config values
nested_list_def: List[NestedListStuff] = [NestedListStuff]
# Nested list configuration -- defaults to coded values
nested_list_def_2: List[NestedListStuffDef] = [
NestedListStuffDef(one=100, two="two"), NestedListStuffDef(one=300, two="four")
]
# Class Enum
class_enum_def: ClassChoice = NestedStuff
# Double Nested class ref
Expand Down Expand Up @@ -282,7 +292,7 @@ class TypeDefaultOptConfig:
# Nested configuration
nested_opt_def: Optional[NestedStuff] = NestedStuff
# Nested list configuration
nested_list_opt_def: Optional[List[NestedListStuff]] = NestedListStuff
nested_list_opt_def: Optional[List[NestedListStuff]] = [NestedListStuff]
# Class Enum
class_enum_opt_def: Optional[ClassChoice] = NestedStuff

Expand Down
4 changes: 4 additions & 0 deletions tests/base/base_asserts_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ def test_all_defaults(self, arg_builder):
assert arg_builder.TypeDefaultConfig.nested_list_def[0].two == "hello"
assert arg_builder.TypeDefaultConfig.nested_list_def[1].one == 20
assert arg_builder.TypeDefaultConfig.nested_list_def[1].two == "bye"
assert arg_builder.TypeDefaultConfig.nested_list_def_2[0].one == 100
assert arg_builder.TypeDefaultConfig.nested_list_def_2[0].two == "two"
assert arg_builder.TypeDefaultConfig.nested_list_def_2[1].one == 300
assert arg_builder.TypeDefaultConfig.nested_list_def_2[1].two == "four"
assert arg_builder.TypeDefaultConfig.class_enum_def.one == 11
assert arg_builder.TypeDefaultConfig.class_enum_def.two == "ciao"
assert (
Expand Down
3 changes: 3 additions & 0 deletions tests/base/test_loaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def arg_builder(monkeypatch):
TypeConfig,
NestedStuff,
NestedListStuff,
NestedListStuffDef,
NestedStuffDefault,
TypeDefaultConfig,
TypeDefaultOptConfig,
Expand Down Expand Up @@ -103,6 +104,7 @@ def arg_builder(monkeypatch):
TypeConfig,
NestedStuff,
NestedListStuff,
NestedListStuffDef,
NestedStuffDefault,
TypeOptConfig,
TypeDefaultConfig,
Expand Down Expand Up @@ -149,6 +151,7 @@ def arg_builder(monkeypatch):
TypeConfig,
NestedStuff,
NestedListStuff,
NestedListStuffDef,
NestedStuffDefault,
TypeOptConfig,
TypeDefaultConfig,
Expand Down
19 changes: 19 additions & 0 deletions tests/base/test_type_specific.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,22 @@ def test_enum_class_missing(self, monkeypatch):
SecondDoubleNestedConfig,
desc="Test Builder"
)


@spock
class RepeatedDefsFailConfig:
# Nested list configuration
nested_list_def: List[NestedListStuff] = [NestedListStuff]


class TestMissingRepeatedDefs:
def test_repeated_defs_fail(self, monkeypatch):
with monkeypatch.context() as m:
m.setattr(
sys,
"argv",
[""],
)
with pytest.raises(SpockInstantiationError):
config = ConfigArgBuilder(RepeatedDefsFailConfig, NestedListStuff, desc="Test Builder")
config.generate()

0 comments on commit f5f1db1

Please sign in to comment.