From 595665a0ca7646139ac7ef079a18f8d144c5611b Mon Sep 17 00:00:00 2001 From: Giles Knap Date: Wed, 12 Jun 2024 08:29:15 +0000 Subject: [PATCH] make args and defines lists into dicts --- convert/ibek2to3.py | 0 src/ibek/args.py | 5 +- src/ibek/definition.py | 6 +- src/ibek/entity_factory.py | 13 ++-- tests/samples/outputs/listarg/st.cmd | 10 ++- .../samples/schemas/ibek.support.schema.json | 74 ++++--------------- .../samples/support/listarg.ibek.support.yaml | 51 +++++++------ 7 files changed, 58 insertions(+), 101 deletions(-) create mode 100644 convert/ibek2to3.py diff --git a/convert/ibek2to3.py b/convert/ibek2to3.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/ibek/args.py b/src/ibek/args.py index 25f8f1e28..817771c70 100644 --- a/src/ibek/args.py +++ b/src/ibek/args.py @@ -36,7 +36,6 @@ def __repr__(self): class Value(BaseSettings): """A calculated string value for a definition""" - name: str = Field(description="Name of the value that the IOC instance will expose") description: str = Field( description="Description of what the value will be used for" ) @@ -50,9 +49,7 @@ class Arg(BaseSettings): """Base class for all Argument Types""" type: str - name: str = Field( - description="Name of the argument that the IOC instance should pass" - ) + description: str = Field( description="Description of what the argument will be used for" ) diff --git a/src/ibek/definition.py b/src/ibek/definition.py index 6206f7d6d..cb8282557 100644 --- a/src/ibek/definition.py +++ b/src/ibek/definition.py @@ -134,16 +134,16 @@ class EntityDefinition(BaseSettings): ) # declare Arg as Union of its subclasses for Pydantic to be able to deserialize - args: Sequence[discriminated] = Field( # type: ignore + args: dict[str, discriminated] = Field( # type: ignore description="The arguments IOC instance should supply", default=(), ) - post_defines: Sequence[Value] = Field( + post_defines: dict[str, Value] = Field( description="Calculated values to use as additional arguments " "With Jinja evaluation after all Args", default=(), ) - pre_defines: Sequence[Value] = Field( + pre_defines: dict[str, Value] = Field( description="Calculated values to use as additional arguments " "With Jinja evaluation before all Args", default=(), diff --git a/src/ibek/entity_factory.py b/src/ibek/entity_factory.py index f5c77588d..493ec386d 100644 --- a/src/ibek/entity_factory.py +++ b/src/ibek/entity_factory.py @@ -62,11 +62,11 @@ def _make_entity_model( Create an Entity Model from a Definition instance and a Support instance. """ - def add_defines(s: Sequence[Value]) -> None: + def add_defines(s: dict[str, Value]) -> None: # add in the pre_defines or post_defines as Args in the Entity - for value in s: + for name, value in s.items(): typ = getattr(builtins, str(value.type)) - add_arg(value.name, typ, value.description, value.value) + add_arg(name, typ, value.description, value.value) def add_arg(name, typ, description, default): if default is None: @@ -105,7 +105,7 @@ def add_arg(name, typ, description, default): add_defines(definition.pre_defines) # add in each of the arguments as a Field in the Entity - for arg in definition.args: + for name, arg in definition.args.items(): type: Any if isinstance(arg, ObjectArg): @@ -123,14 +123,13 @@ def add_arg(name, typ, description, default): for k, v in arg.values.items(): enum_swapped[str(v) if v else str(k)] = k # TODO review enums especially with respect to Pydantic 2.7.1 - val_enum = EnumVal(arg.name, enum_swapped) # type: ignore + val_enum = EnumVal(name, enum_swapped) # type: ignore type = val_enum else: # arg.type is str, int, float, etc. type = getattr(builtins, arg.type) - # TODO look into why arg.name requires type ignore - add_arg(arg.name, type, arg.description, getattr(arg, "default")) # type: ignore + add_arg(name, type, arg.description, getattr(arg, "default")) # add in the calculated values Jinja Templates as Fields in the Entity add_defines(definition.post_defines) diff --git a/tests/samples/outputs/listarg/st.cmd b/tests/samples/outputs/listarg/st.cmd index 47609c763..0d2577396 100644 --- a/tests/samples/outputs/listarg/st.cmd +++ b/tests/samples/outputs/listarg/st.cmd @@ -5,8 +5,9 @@ dbLoadDatabase dbd/ioc.dbd ioc_registerRecordDeviceDriver pdbbase - -Lister, age 3000029, who does not like to hear "Smoke me a kipper, I'll be back for breakfast" has friends: +Lister, age 3000029, who does not like to hear + "Smoke me a kipper, I'll be back for breakfast" +has friends- o Rimmer o Cat o Kryten @@ -16,8 +17,9 @@ First friend is Rimmer Time vortex friends are ['Cat', 'Cat', 'Cat', 'Holly', 'Holly', 'Holly', 'Kryten', 'Kryten', 'Kryten', 'Rimmer', 'Rimmer', 'Rimmer'] Fist time vortex friend is Cat - -Lister, age 42, who does not like to hear "Smoke me a kipper, I'll be back for breakfast" has friends: +Lister, age 42, who does not like to hear + "Smoke me a kipper, I'll be back for breakfast" +has friends- o Rimmer o Cat o Kryten diff --git a/tests/samples/schemas/ibek.support.schema.json b/tests/samples/schemas/ibek.support.schema.json index 10ce63f4a..ec202cb04 100644 --- a/tests/samples/schemas/ibek.support.schema.json +++ b/tests/samples/schemas/ibek.support.schema.json @@ -13,11 +13,6 @@ "title": "Type", "type": "string" }, - "name": { - "description": "Name of the argument that the IOC instance should pass", - "title": "Name", - "type": "string" - }, "description": { "description": "Description of what the argument will be used for", "title": "Description", @@ -42,7 +37,6 @@ } }, "required": [ - "name", "description" ], "title": "BoolArg", @@ -133,9 +127,7 @@ "type": "string" }, "args": { - "default": [], - "description": "The arguments IOC instance should supply", - "items": { + "additionalProperties": { "description": "union of arg types", "discriminator": { "mapping": { @@ -173,26 +165,28 @@ } ] }, + "default": [], + "description": "The arguments IOC instance should supply", "title": "Args", - "type": "array" + "type": "object" }, "post_defines": { - "default": [], - "description": "Calculated values to use as additional arguments With Jinja evaluation after all Args", - "items": { + "additionalProperties": { "$ref": "#/$defs/Value" }, + "default": [], + "description": "Calculated values to use as additional arguments With Jinja evaluation after all Args", "title": "Post Defines", - "type": "array" + "type": "object" }, "pre_defines": { - "default": [], - "description": "Calculated values to use as additional arguments With Jinja evaluation before all Args", - "items": { + "additionalProperties": { "$ref": "#/$defs/Value" }, + "default": [], + "description": "Calculated values to use as additional arguments With Jinja evaluation before all Args", "title": "Pre Defines", - "type": "array" + "type": "object" }, "databases": { "default": [], @@ -343,11 +337,6 @@ "title": "Type", "type": "string" }, - "name": { - "description": "Name of the argument that the IOC instance should pass", - "title": "Name", - "type": "string" - }, "description": { "description": "Description of what the argument will be used for", "title": "Description", @@ -370,7 +359,6 @@ } }, "required": [ - "name", "description", "values" ], @@ -412,11 +400,6 @@ "title": "Type", "type": "string" }, - "name": { - "description": "Name of the argument that the IOC instance should pass", - "title": "Name", - "type": "string" - }, "description": { "description": "Description of what the argument will be used for", "title": "Description", @@ -441,7 +424,6 @@ } }, "required": [ - "name", "description" ], "title": "FloatArg", @@ -460,11 +442,6 @@ "title": "Type", "type": "string" }, - "name": { - "description": "Name of the argument that the IOC instance should pass", - "title": "Name", - "type": "string" - }, "description": { "description": "Description of what the argument will be used for", "title": "Description", @@ -484,7 +461,6 @@ } }, "required": [ - "name", "description" ], "title": "IdArg", @@ -503,11 +479,6 @@ "title": "Type", "type": "string" }, - "name": { - "description": "Name of the argument that the IOC instance should pass", - "title": "Name", - "type": "string" - }, "description": { "description": "Description of what the argument will be used for", "title": "Description", @@ -532,7 +503,6 @@ } }, "required": [ - "name", "description" ], "title": "IntArg", @@ -551,11 +521,6 @@ "title": "Type", "type": "string" }, - "name": { - "description": "Name of the argument that the IOC instance should pass", - "title": "Name", - "type": "string" - }, "description": { "description": "Description of what the argument will be used for", "title": "Description", @@ -576,7 +541,6 @@ } }, "required": [ - "name", "description" ], "title": "ObjectArg", @@ -595,11 +559,6 @@ "title": "Type", "type": "string" }, - "name": { - "description": "Name of the argument that the IOC instance should pass", - "title": "Name", - "type": "string" - }, "description": { "description": "Description of what the argument will be used for", "title": "Description", @@ -619,7 +578,6 @@ } }, "required": [ - "name", "description" ], "title": "StrArg", @@ -680,11 +638,6 @@ "additionalProperties": false, "description": "A calculated string value for a definition", "properties": { - "name": { - "description": "Name of the value that the IOC instance will expose", - "title": "Name", - "type": "string" - }, "description": { "description": "Description of what the value will be used for", "title": "Description", @@ -705,7 +658,6 @@ } }, "required": [ - "name", "description", "value" ], @@ -764,4 +716,4 @@ ], "title": "Support", "type": "object" -} \ No newline at end of file +} diff --git a/tests/samples/support/listarg.ibek.support.yaml b/tests/samples/support/listarg.ibek.support.yaml index b53fe6123..23ba45f9c 100644 --- a/tests/samples/support/listarg.ibek.support.yaml +++ b/tests/samples/support/listarg.ibek.support.yaml @@ -4,44 +4,50 @@ # 'jinja str/type' capability in Arg default values module: listtest +shared: + - args1: &args1 + quote: + type: str + description: |- + most hated quote + default: |- + Smoke me a kipper, I'll be back for breakfast + + - args2: &args2 + age: + type: int + description: |- + Age of the character including cryogenic sleep + # example int using Jinja + default: |- + {{ 29 + cryo_years }} + defs: - name: lister description: |- The protagonist from Red Dwarf pre_defines: - - name: name + name: description: |- name of the character value: |- Dave Lister args: - - type: str - name: quote - description: |- - most hated quote - default: |- - Smoke me a kipper, I'll be back for breakfast + # example of using aliases to merge multiple dictionaries into this one + <<: [*args1, *args2] - - type: bool - name: is_human + is_human: + type: bool description: |- is the character human # example bool using Jinja default: |- {{ name == 'Dave Lister' }} - - type: int - name: age - description: |- - Age of the character including cryogenic sleep - # example int using Jinja - default: |- - {{ 29 + cryo_years }} - post_defines: - - name: cryo_years + cryo_years: description: |- years in cryogenic sleep type: int @@ -49,7 +55,7 @@ defs: # https://en.wikipedia.org/wiki/Dave_Lister#:~:text=As%20a%20result%2C%20Holly%20keeps,radiation%20levels%20return%20to%20normal. # example type list value not using Jinja - - name: friends + friends: description: |- friends of Lister type: list @@ -60,7 +66,7 @@ defs: - Holly # example type list value using Jinja - - name: time_vortex + time_vortex: description: |- friends after the Time Hole episode type: list @@ -70,8 +76,9 @@ defs: pre_init: - value: | - - Lister, age {{age}}, who does not like to hear "{{quote}}" has friends: + Lister, age {{age}}, who does not like to hear + "{{quote}}" + has friends- {#- example Jinja loop which is discouraged, but demos we have a list -#} {%- for friend in friends %} o {{friend}}