diff --git a/policyengine_core/parameters/parameter.py b/policyengine_core/parameters/parameter.py index 38dbb090..5127b3e3 100644 --- a/policyengine_core/parameters/parameter.py +++ b/policyengine_core/parameters/parameter.py @@ -3,7 +3,7 @@ from typing import Dict, List, Optional import numpy - +from collections import OrderedDict from policyengine_core.commons.misc import empty_clone from policyengine_core.errors import ParameterParsingError from policyengine_core.periods import INSTANT_PATTERN, period as get_period @@ -239,7 +239,7 @@ def relative_change(self, start_instant, end_instant): return end_value / start_value - 1 def get_attr_dict(self) -> dict: - data = self.__dict__.copy() + data = OrderedDict(self.__dict__.copy()) for attr in self._exclusion_list: if attr in data.keys(): del data[attr] @@ -251,4 +251,5 @@ def get_attr_dict(self) -> dict: value = float(value) value_dict[value_at_instant.instant_str] = value data["values_list"] = value_dict - return data + data.move_to_end("values_list") + return dict(data) diff --git a/policyengine_core/parameters/parameter_node.py b/policyengine_core/parameters/parameter_node.py index 4f44cc0a..2dd0fd8c 100644 --- a/policyengine_core/parameters/parameter_node.py +++ b/policyengine_core/parameters/parameter_node.py @@ -5,6 +5,7 @@ from typing import Iterable, Union import yaml +from collections import OrderedDict from policyengine_core import commons, parameters, tools from policyengine_core.periods.instant_ import Instant @@ -280,7 +281,7 @@ def get_child(self, path: str) -> "ParameterNode": return node def get_attr_dict(self) -> dict: - data = self.__dict__.copy() + data = OrderedDict(self.__dict__.copy()) for attr in self._exclusion_list: if attr in data.keys(): del data[attr] @@ -288,8 +289,9 @@ def get_attr_dict(self) -> dict: child_dict = data.get("children") for child_name, child in child_dict.items(): data[child_name] = child.get_attr_dict() - del data["children"] - return data + data.move_to_end(child_name) + del data["children"] + return dict(data) class NoAliasDumper(yaml.SafeDumper): def ignore_aliases(self, data): diff --git a/policyengine_core/parameters/parameter_scale.py b/policyengine_core/parameters/parameter_scale.py index 851462de..2d9a1c14 100644 --- a/policyengine_core/parameters/parameter_scale.py +++ b/policyengine_core/parameters/parameter_scale.py @@ -2,7 +2,7 @@ import os import typing from typing import Any, Iterable - +from collections import OrderedDict from policyengine_core import commons, parameters, tools from policyengine_core.errors import ParameterParsingError from policyengine_core.parameters import AtInstantLike, config, helpers @@ -174,7 +174,7 @@ def _get_at_instant(self, instant: Instant) -> TaxScaleLike: return scale def get_attr_dict(self) -> dict: - data = self.__dict__.copy() + data = OrderedDict(self.__dict__.copy()) for attr in self._exclusion_list: if attr in data.keys(): del data[attr] @@ -185,4 +185,5 @@ def get_attr_dict(self) -> dict: node_list[i] = node.get_attr_dict() i += 1 data["brackets"] = node_list - return data + data.move_to_end("brackets") + return dict(data)