Skip to content

Commit

Permalink
Merge pull request #1573 from talyz/mapping-types
Browse files Browse the repository at this point in the history
ImmutableValidatedObject: Support nested Mapping types
  • Loading branch information
roberth authored Dec 17, 2023
2 parents 2cfc2cb + e43c82f commit 053668e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 16 deletions.
41 changes: 27 additions & 14 deletions nixops/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
import re
import typing
import typeguard # type: ignore
import inspect
import shlex
import collections.abc
from inspect import isclass
from typing import (
Callable,
List,
Expand Down Expand Up @@ -149,21 +150,33 @@ def _transform_value(key: Any, value: Any) -> Any:
if not ann:
return value

if inspect.isclass(ann) and issubclass(ann, ImmutableValidatedObject):
if isclass(ann) and issubclass(ann, ImmutableValidatedObject):
value = ann(**value)

# Support Sequence[ImmutableValidatedObject]
if isinstance(value, tuple) and not isinstance(ann, str):
new_value = []
for v in value:
for subann in ann.__args__: # type: ignore
if inspect.isclass(subann) and issubclass(
subann, ImmutableValidatedObject
):
new_value.append(subann(**v))
else:
new_value.append(v)
value = tuple(new_value)
# Support containers of ImmutableValidatedObjects
match typing.get_origin(ann):

case collections.abc.Sequence:
sequence: List = []
for v in value:
for subann in typing.get_args(ann):
if isclass(subann) and issubclass(
subann, ImmutableValidatedObject
):
sequence.append(subann(**v))
else:
sequence.append(v)
value = tuple(sequence)

case collections.abc.Mapping:
_, value_ann = typing.get_args(ann)
if isclass(value_ann) and issubclass(
value_ann, ImmutableValidatedObject
):
mapping: Dict = {}
for k, v in value.items():
mapping[k] = value_ann(**v)
value = mapping

typeguard.check_type(value, ann)

Expand Down
14 changes: 12 additions & 2 deletions tests/unit/test_util.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Sequence
from typing import Any, Sequence, Mapping
import json
from nixops.logger import Logger
from io import StringIO
Expand Down Expand Up @@ -121,4 +121,14 @@ class B(A):
class WithSequence(util.ImmutableValidatedObject):
subs: Sequence[SubResource]

WithSequence(subs=[SubResource(x=1), SubResource(x=2)])
seq = WithSequence(subs=[{"x": 1}, {"x": 2}])
for i in seq.subs:
self.assertIsInstance(i, SubResource)

# Test Mapping[str, ImmutableValidatedObject]
class WithMapping(util.ImmutableValidatedObject):
mapping: Mapping[str, SubResource]

mapped = WithMapping(mapping={"aaa": {"x": 1}, "bbb": {"x": 2}})
for _, v in mapped.mapping.items():
self.assertIsInstance(v, SubResource)

0 comments on commit 053668e

Please sign in to comment.