From 9f59e4fe26d14145ce1eb83d8b99c55ef9e53a24 Mon Sep 17 00:00:00 2001 From: Adam Souzis Date: Sun, 29 Sep 2024 03:47:19 -0700 Subject: [PATCH] dsl: Add OpenDataType.extend() helper method to add undeclared properties. --- tests/examples/dsl_configurator.py | 2 +- tests/test_constraints.py | 4 +++- tests/test_dsl.py | 5 ++++- tosca-package/tosca/_tosca.py | 6 ++++++ unfurl/configurators/templates/docker.py | 4 ++-- 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/tests/examples/dsl_configurator.py b/tests/examples/dsl_configurator.py index 43b61756..47b1c45d 100644 --- a/tests/examples/dsl_configurator.py +++ b/tests/examples/dsl_configurator.py @@ -35,7 +35,7 @@ def run(self, task: TaskView) -> bool: extra = self.a_requirement.extra # type: ignore self.a_requirement.copy_of_extra = extra # type: ignore - self.data_list.append(MyDataType()) + self.data_list.append(MyDataType().extend(additional=1)) self.data_list[0].ports.source = port80 self.data_list[0].ports.target = tosca.datatypes.NetworkPortDef(8080) return True diff --git a/tests/test_constraints.py b/tests/test_constraints.py index a6381ee3..63ba8d38 100644 --- a/tests/test_constraints.py +++ b/tests/test_constraints.py @@ -301,6 +301,7 @@ def test_computed_properties(): "source": 80, "source_range": None, }, + "a_list": [1], "data_list": [ { @@ -310,7 +311,8 @@ def test_computed_properties(): "target_range": None, "source": 80, "source_range": None, - } + }, + "additional": 1 } ], "extra": "extra", diff --git a/tests/test_dsl.py b/tests/test_dsl.py index 3d40e389..660ef987 100644 --- a/tests/test_dsl.py +++ b/tests/test_dsl.py @@ -782,6 +782,7 @@ def test_envvar_type(): import tosca from tosca import Property, DEFAULT import unfurl + from unfurl.configurators.templates.docker import unfurl_datatypes_DockerContainer with tosca.set_evaluation_mode("spec"): @@ -820,8 +821,10 @@ class pcls(tosca.InstanceProxy): generic_envvars = unfurl.datatypes.EnvironmentVariables(DBASE="aaaa", URL=True) assert generic_envvars.to_yaml() == {"DBASE": "aaaa", "URL": True} - assert OpenDataType(a=1, b="b").to_yaml() == {"a": 1, "b": "b"} + assert OpenDataType(a=1, b="b").extend(c="c").to_yaml() == {"a": 1, "b": "b", "c": "c"} assert Namespace.MyDataType(name="foo").to_yaml() == {"name": "foo"} + # make sure DockerContainer is an OpenDataType + unfurl_datatypes_DockerContainer().extend(labels=dict(foo="bar")) test_relationship_yaml = """ diff --git a/tosca-package/tosca/_tosca.py b/tosca-package/tosca/_tosca.py index ccc7f827..395cb296 100644 --- a/tosca-package/tosca/_tosca.py +++ b/tosca-package/tosca/_tosca.py @@ -1925,6 +1925,7 @@ def _make_dataclass(cls): # we need _Tosca_Fields not dataclasses.Fields # so for any declarations of tosca fields (properties, requirements, etc) # missing a _Tosca_Fields, set one before calling _process_class() + global_state.mode = "spec" global_state._in_process_class = True try: annotations = cls.__dict__.get("__annotations__") @@ -3183,6 +3184,11 @@ def __init__(self, _name="", **kw): self.__dict__[k] = kw.pop(k) super().__init__(_name, **kw) + def extend(self, **kw) -> Self: + "Add undeclared properties to the data type." + self.__dict__.update(kw) + return self + class CapabilityType(_OwnedToscaType): _type_section: ClassVar[str] = "capability_types" diff --git a/unfurl/configurators/templates/docker.py b/unfurl/configurators/templates/docker.py index 7ec55ab2..92593613 100644 --- a/unfurl/configurators/templates/docker.py +++ b/unfurl/configurators/templates/docker.py @@ -22,15 +22,15 @@ ToscaOutputs, operation, valid_values, + OpenDataType ) import tosca import unfurl.configurators.ansible from unfurl.tosca_plugins.artifacts import * -class unfurl_datatypes_DockerContainer(DataType): +class unfurl_datatypes_DockerContainer(OpenDataType): _type_name = "unfurl.datatypes.DockerContainer" - _type_metadata = {"additionalProperties": True} environment: Union["unfurl.datatypes.EnvironmentVariables", None] = Property( factory=lambda: (unfurl.datatypes.EnvironmentVariables()) )