diff --git a/mira/metamodel/template_model.py b/mira/metamodel/template_model.py index 8570ced4..fc59a7ec 100644 --- a/mira/metamodel/template_model.py +++ b/mira/metamodel/template_model.py @@ -1,3 +1,5 @@ +import copy + from pydantic import ConfigDict __all__ = [ @@ -473,6 +475,8 @@ def from_json(cls, data) -> "TemplateModel": : Returns the newly created template model. """ + # Do a copy just to make sure we don't modify the original data + data = copy.deepcopy(data) local_symbols = {p: sympy.Symbol(p) for p in data.get("parameters", [])} for template_dict in data.get("templates", []): # We need to figure out the template class based on the type diff --git a/mira/metamodel/templates.py b/mira/metamodel/templates.py index df477822..88523a00 100644 --- a/mira/metamodel/templates.py +++ b/mira/metamodel/templates.py @@ -3,6 +3,8 @@ Regenerate the JSON schema by running ``python -m mira.metamodel.schema``. """ +import copy + from pydantic import ConfigDict from typing import Literal @@ -376,6 +378,8 @@ def from_json(cls, data) -> "Concept": if isinstance(data, Concept): return data elif data.get('units'): + # Copy so we don't update the input + data = copy.deepcopy(data) data['units'] = Unit.from_json(data['units']) return cls(**data) @@ -413,6 +417,8 @@ def from_json(cls, data, rate_symbols=None) -> "Template": : A Template object """ + # Make a copy to make sure we don't update the input + data = copy.deepcopy(data) # We make sure to use data such that it's not modified in place, # e.g., we don't use pop or overwrite items, otherwise this function # would have unintended side effects. diff --git a/mira/metamodel/units.py b/mira/metamodel/units.py index 1b28ec2f..ad87d049 100644 --- a/mira/metamodel/units.py +++ b/mira/metamodel/units.py @@ -42,8 +42,8 @@ class Unit(BaseModel): @classmethod def from_json(cls, data: Dict[str, Any]) -> "Unit": - # Use get_sympy from amr.petrinet, but avoid circular import - from mira.sources.amr.petrinet import get_sympy + # Use get_sympy from sources, but avoid circular import + from mira.sources.util import get_sympy new_data = data.copy() new_data["expression"] = get_sympy(data, local_dict=UNIT_SYMBOLS) assert (new_data.get('expression') is None or