From bef8e5b09daf7d0e30bfcc59b1c3ed542394eddb Mon Sep 17 00:00:00 2001 From: Adamantios Date: Fri, 9 Aug 2024 13:52:50 +0300 Subject: [PATCH] fix: the type of numeric keys for overrides This is a workaround to fix the types of numeric keys as they can only be represented as strings in the json overrides. --- aea/configurations/validation.py | 18 +++++++++++++++++- aea/helpers/base.py | 10 ++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/aea/configurations/validation.py b/aea/configurations/validation.py index aff4217080..72a6e34459 100644 --- a/aea/configurations/validation.py +++ b/aea/configurations/validation.py @@ -18,11 +18,13 @@ # # ------------------------------------------------------------------------------ """Implementation of the configuration validation.""" + import inspect import json import os from collections import OrderedDict from copy import deepcopy +from functools import reduce from pathlib import Path from typing import Any, Dict, Iterator, List, Optional, Tuple @@ -36,7 +38,7 @@ from aea.configurations.constants import AGENT from aea.configurations.data_types import ComponentId, ComponentType, PublicId from aea.exceptions import AEAValidationError -from aea.helpers.base import dict_to_path_value +from aea.helpers.base import dict_to_path_value, update_nested_dict from aea.helpers.env_vars import is_env_variable from aea.helpers.io import open_file @@ -301,6 +303,20 @@ def validate_data_with_pattern( overrides = {tuple(path): value for path, value in dict_to_path_value(data)} errors = [] + # this is a workaround to fix the type of numeric keys as they can only be represented as strs in the json overrides + for path in original_config: + path_as_str = tuple(map(str, path)) + if path_as_str in overrides and path not in overrides: + value = overrides[path_as_str] + del overrides[path_as_str] + up_to_last_key = data + for key in path_as_str[:-1]: + up_to_last_key = up_to_last_key[key] + del up_to_last_key[path_as_str[-1]] + overrides[path] = value + vals = reduce(lambda d, key: {key: d}, reversed(path), value) + update_nested_dict(data, vals) + def check_excludes(path: Tuple[str, ...]) -> bool: for exclude in excludes_: if len(exclude) > len(path): # pragma: nocover diff --git a/aea/helpers/base.py b/aea/helpers/base.py index ce594135ae..95c562a6fb 100644 --- a/aea/helpers/base.py +++ b/aea/helpers/base.py @@ -1091,3 +1091,13 @@ def prepend_if_not_absolute(path: PathLike, prefix: PathLike) -> PathLike: :return: the same path if absolute, else the prepended path. """ return path if Path(path).is_absolute() else Path(prefix) / path + + +def update_nested_dict(dict_: dict, nested_update: dict) -> dict: + """Update a nested dictionary.""" + for key, value in nested_update.items(): + if isinstance(value, dict): + dict_[key] = update_nested_dict(dict_.get(key, {}), value) + else: + dict_[key] = value + return dict_