Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

switch to Entity.__dict__ instead of __context__ #69

Merged
merged 2 commits into from
May 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 13 additions & 17 deletions src/ibek/ioc.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import builtins
import types
from dataclasses import Field, asdict, dataclass, field, make_dataclass
from dataclasses import Field, dataclass, field, make_dataclass
from typing import Any, Dict, List, Mapping, Sequence, Tuple, Type, cast

from apischema import (
Expand All @@ -27,7 +27,7 @@
from . import modules
from .globals import T, desc
from .support import Definition, IdArg, ObjectArg, Support
from .utils import Utils
from .utils import UTILS


class Entity:
Expand All @@ -38,10 +38,6 @@ class Entity:

# a link back to the Definition Object that generated this Definition
__definition__: Definition
# a singleton Utility object for sharing state across all Entity renders
__utils__: Utils = Utils()
# Context of expanded args and values to be passed to all Jinja expansion
__context__: Dict[str, Any]

entity_enabled: bool

Expand All @@ -56,22 +52,22 @@ def __post_init__(self: "Entity"):
assert inst_id not in id_to_entity, f"Already got an instance {inst_id}"
id_to_entity[inst_id] = self

# create a context dictionary for use in Jinja expansion of this Entity
context: Dict[str, Any] = asdict(self) # type: ignore
for value in self.__definition__.values:
context[value.name] = value.value
# TODO - not working as printing own ID
setattr(self, "__str__", inst_id)

# add in the global __utils__ object for state sharing
context["__utils__"] = self.__utils__
self.__utils__ = UTILS

# copy 'values' from the definition into the Entity
for value in self.__definition__.values:
setattr(self, value.name, value.value)

# Do Jinja expansion of any string args/values in the context
for arg, value in context.items():
# Jinja expansion of any string args/values in the Entity's attributes
for arg, value in self.__dict__.items():
if isinstance(value, str):
jinja_template = Template(value)
rendered = jinja_template.render(context)
context[arg] = rendered

self.__context__ = context
rendered = jinja_template.render(self.__dict__)
setattr(self, arg, rendered)


id_to_entity: Dict[str, Entity] = {}
Expand Down
13 changes: 4 additions & 9 deletions src/ibek/render.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def render_text(self, instance: Entity, text: str, once=False, suffix="") -> str

# Render Jinja entries in the text
jinja_template = Template(text)
result = jinja_template.render(instance.__context__) # type: ignore
result = jinja_template.render(instance.__dict__) # type: ignore

if result == "":
return ""
Expand Down Expand Up @@ -107,7 +107,7 @@ def render_database(self, instance: Entity) -> Optional[str]:

include_list = []
for arg in template.include_args:
if arg in instance.__context__:
if arg in instance.__dict__:
include_list.append(f"{arg}={{{{ {arg} }}}}")
else:
raise ValueError(
Expand All @@ -122,12 +122,7 @@ def render_database(self, instance: Entity) -> Optional[str]:
)

jinja_template = Template(jinja_txt)
db_txt = jinja_template.render(instance.__context__) # type: ignore

# run the result through jinja again so we can refer to args for arg defaults

db_template = Template(db_txt)
db_txt = db_template.render(instance.__context__) # type: ignore
db_txt = jinja_template.render(instance.__dict__) # type: ignore

return db_txt + "\n"

Expand All @@ -144,7 +139,7 @@ def render_environment_variables(self, instance: Entity) -> Optional[str]:
for variable in variables:
# Substitute the name and value of the environment variable from args
env_template = Template(f"epicsEnvSet {variable.name} {variable.value}")
env_var_txt += env_template.render(instance.__context__)
env_var_txt += env_template.render(instance.__dict__)
return env_var_txt + "\n"

def render_post_ioc_init(self, instance: Entity) -> Optional[str]:
Expand Down
4 changes: 4 additions & 0 deletions src/ibek/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,7 @@ def counter(
self.counters[name] = counter

return result


# a singleton Utility object for sharing state across all Entity renders
UTILS: Utils = Utils()
25 changes: 22 additions & 3 deletions tests/samples/schemas/all.ibek.support.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1349,9 +1349,9 @@
"type": "boolean",
"default": true
},
"device": {
"name": {
"type": "string",
"description": "Device Name, channel name until the last colon, up to 16 chars",
"description": "A name this IP module",
"vscode_ibek_plugin_type": "type_id"
},
"carrier": {
Expand Down Expand Up @@ -1380,7 +1380,7 @@
}
},
"required": [
"device",
"name",
"carrier",
"ip_site_number",
"interrupt_vector"
Expand All @@ -1394,6 +1394,20 @@
"type": "boolean",
"default": true
},
"device": {
"type": "string",
"description": "Device Name, PV Suffix",
"vscode_ibek_plugin_type": "type_id"
},
"ip_module": {
"type": "string",
"description": "PscIpModule object",
"vscode_ibek_plugin_type": "type_object"
},
"link": {
"type": "integer",
"description": "Link number on this IP module (0 or 1)"
},
"i_abserr": {
"type": "integer",
"description": "todo",
Expand Down Expand Up @@ -1480,6 +1494,11 @@
"default": "psc.PscTemplate"
}
},
"required": [
"device",
"ip_module",
"link"
],
"additionalProperties": false
},
{
Expand Down
9 changes: 5 additions & 4 deletions tests/test_ioc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

from typer.testing import CliRunner

from ibek.ioc import Entity, clear_entity_classes
from ibek.ioc import clear_entity_classes
from ibek.utils import UTILS

from .test_cli import run_cli

Expand All @@ -18,7 +19,7 @@ def test_example_ioc(tmp_path: Path, samples: Path, ibek_defs: Path):
verifies that it starts up correctly.
"""
clear_entity_classes()
Entity.__utils__.__reset__()
UTILS.__reset__()

tmp_path = Path("/tmp/ibek_test")
tmp_path.mkdir(exist_ok=True)
Expand Down Expand Up @@ -60,7 +61,7 @@ def test_example_sr_rf_08(tmp_path: Path, samples: Path, ibek_defs: Path):
"""

clear_entity_classes()
Entity.__utils__.__reset__()
UTILS.__reset__()

tmp_path = Path("/tmp/ibek_test2")
tmp_path.mkdir(exist_ok=True)
Expand Down Expand Up @@ -104,7 +105,7 @@ def test_values_ioc(tmp_path: Path, samples: Path, ibek_defs: Path):
"""

clear_entity_classes()
Entity.__utils__.__reset__()
UTILS.__reset__()

tmp_path = Path("/tmp/ibek_test2")
tmp_path.mkdir(exist_ok=True)
Expand Down