diff --git a/.spelling b/.spelling
index 8efb3ebb52..405acc5c29 100644
--- a/.spelling
+++ b/.spelling
@@ -3,6 +3,7 @@
# global dictionary is at the start, file overrides afterwards
# one word per line, to define a file override use ' - filename'
# where filename is relative to this configuration file
+fraxtal
Flashbots
liveness
pre-shared
diff --git a/HISTORY.md b/HISTORY.md
index c9ad35aff0..10ab46ab72 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -1,5 +1,10 @@
# Release History - open AEA
+## 1.58.0 (2024-10-03)
+
+AEA:
+- Adds support for dictionary overrides #750, #761
+
## 1.57.0 (2024-09-24)
AEA:
diff --git a/SECURITY.md b/SECURITY.md
index 6059da7f4c..c0aa0f6514 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -8,8 +8,8 @@ The following table shows which versions of `open-aea` are currently being suppo
| Version | Supported |
|------------| ------------------ |
-| `1.57.x` | :white_check_mark: |
-| `< 1.57.0` | :x: |
+| `1.58.x` | :white_check_mark: |
+| `< 1.58.0` | :x: |
## Reporting a Vulnerability
diff --git a/aea/__version__.py b/aea/__version__.py
index d68f585c79..08aa85260f 100644
--- a/aea/__version__.py
+++ b/aea/__version__.py
@@ -23,7 +23,7 @@
__title__ = "open-aea"
__description__ = "Open Autonomous Economic Agent framework (without vendor lock-in)"
__url__ = "https://github.com/valory-xyz/open-aea.git"
-__version__ = "1.57.0"
+__version__ = "1.58.0"
__author__ = "Valory AG"
__license__ = "Apache-2.0"
__copyright__ = "2021 Valory AG, 2019 Fetch.AI Limited"
diff --git a/aea/configurations/validation.py b/aea/configurations/validation.py
index 568194e311..838c02b086 100644
--- a/aea/configurations/validation.py
+++ b/aea/configurations/validation.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
#
-# Copyright 2022-2023 Valory AG
+# Copyright 2022-2024 Valory AG
# Copyright 2018-2021 Fetch.AI Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -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
@@ -295,12 +297,26 @@ def validate_data_with_pattern(
excludes_: List[Tuple[str]] = []
else:
excludes_ = excludes
- pattern_path_value = {
+ original_config = {
tuple(path): value for path, value in dict_to_path_value(pattern)
}
- data_path_value = {tuple(path): value for path, value in dict_to_path_value(data)}
+ 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
@@ -315,17 +331,17 @@ def is_a_dict_override(path: Tuple[str, ...]) -> bool:
flag = False
while len(path) > 0:
path = path[:-1]
- if path in pattern_path_value:
- pattern_value = pattern_path_value[path]
+ if path in original_config:
+ pattern_value = original_config[path]
flag = isinstance(pattern_value, OrderedDict)
break
return flag
- for path, new_value in data_path_value.items():
+ for path, new_value in overrides.items():
if check_excludes(path):
continue
- if path not in pattern_path_value:
+ if path not in original_config:
if not is_a_dict_override(path=(*path,)):
errors.append(
f"Attribute `{'.'.join(path)}` is not allowed to be updated!"
@@ -333,7 +349,7 @@ def is_a_dict_override(path: Tuple[str, ...]) -> bool:
continue
- pattern_value = pattern_path_value[path]
+ pattern_value = original_config[path]
if pattern_value is None:
# not possible to determine data type for optional value not set
diff --git a/aea/helpers/base.py b/aea/helpers/base.py
index 0594494d7a..785989bfd8 100644
--- a/aea/helpers/base.py
+++ b/aea/helpers/base.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
#
-# Copyright 2022-2023 Valory AG
+# Copyright 2022-2024 Valory AG
# Copyright 2018-2021 Fetch.AI Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -711,10 +711,14 @@ def dict_to_path_value(
"""Convert dict to sequence of terminal path build of keys and value."""
path = path or []
for key, value in data.items():
+ # terminal value
if isinstance(value, Mapping) and value:
- # terminal value
+ # yielding here allows for higher level dict overriding
+ yield path + [key], value
+ # recursing to the next level of the dict
for p, v in dict_to_path_value(value, path + [key]):
yield p, v
+ # non-terminal value
else:
yield path + [key], value
@@ -1087,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_
diff --git a/aea/helpers/env_vars.py b/aea/helpers/env_vars.py
index 43f62f4b5b..d1b865a8ae 100644
--- a/aea/helpers/env_vars.py
+++ b/aea/helpers/env_vars.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
#
-# Copyright 2022-2023 Valory AG
+# Copyright 2022-2024 Valory AG
# Copyright 2018-2019 Fetch.AI Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -34,6 +34,11 @@
ENV_VARIABLE_RE = re.compile(r"^\$\{(([A-Z0-9_]+):?)?([a-z]+)?(:(.+))?}$")
+MODELS = "models"
+ARGS = "args"
+ARGS_LEVEL_FROM_MODELS = 2
+ARG_LEVEL_FROM_MODELS = ARGS_LEVEL_FROM_MODELS + 1
+RESTRICTION_EXCEPTIONS = frozenset({"setup", "genesis_config"})
def is_env_variable(value: Any) -> bool:
@@ -41,10 +46,35 @@ def is_env_variable(value: Any) -> bool:
return isinstance(value, str) and bool(ENV_VARIABLE_RE.match(value))
-def export_path_to_env_var_string(export_path: List[str]) -> str:
- """Conver export path to environment variable string."""
+def restrict_model_args(export_path: List[str]) -> Tuple[List[str], List[str]]:
+ """Do not allow more levels than one for a model's argument."""
+ restricted = []
+ result = []
+ for i, current_path in enumerate(export_path):
+ result.append(current_path)
+ args_level = i + ARGS_LEVEL_FROM_MODELS
+ arg_level = i + ARG_LEVEL_FROM_MODELS
+ if (
+ current_path == MODELS
+ and arg_level < len(export_path)
+ and export_path[args_level] == ARGS
+ and export_path[arg_level] not in RESTRICTION_EXCEPTIONS
+ ):
+ # do not allow more levels than one for a model's argument
+ arg_content_level = arg_level + 1
+ result.extend(export_path[i + 1 : arg_content_level])
+ # store the restricted part of the path
+ for j in range(arg_content_level, len(export_path)):
+ restricted.append(export_path[j])
+ break
+ return restricted, result
+
+
+def export_path_to_env_var_string(export_path: List[str]) -> Tuple[List[str], str]:
+ """Convert export path to environment variable string."""
+ restricted, export_path = restrict_model_args(export_path)
env_var_string = "_".join(map(str, export_path))
- return env_var_string.upper()
+ return restricted, env_var_string.upper()
NotSet = object()
@@ -149,7 +179,7 @@ def apply_env_variables(
data,
env_variables,
default_value,
- default_var_name=export_path_to_env_var_string(export_path=path),
+ default_var_name=export_path_to_env_var_string(export_path=path)[1],
)
return data
@@ -242,35 +272,76 @@ def is_strict_list(data: Union[List, Tuple]) -> bool:
return is_strict
+def list_to_nested_dict(lst: list, val: Any) -> dict:
+ """Convert a list to a nested dict."""
+ nested_dict = val
+ for item in reversed(lst):
+ nested_dict = {item: nested_dict}
+ return nested_dict
+
+
+def ensure_dict(dict_: Dict[str, Union[dict, str]]) -> dict:
+ """Return the given dictionary converting any values which are json strings as dicts."""
+ return {k: json.loads(v) for k, v in dict_.items() if isinstance(v, str)}
+
+
+def ensure_json_content(dict_: dict) -> dict:
+ """Return the given dictionary converting any nested dictionary values as json strings."""
+ return {k: json.dumps(v) for k, v in dict_.items() if isinstance(v, dict)}
+
+
+def merge_dicts(a: dict, b: dict) -> dict:
+ """Merge two dictionaries."""
+ # shallow copy of `a`
+ merged = {**a}
+ for key, value in b.items():
+ if key in merged and isinstance(merged[key], dict) and isinstance(value, dict):
+ # recursively merge nested dictionaries
+ merged[key] = merge_dicts(merged[key], value)
+ else:
+ # if not a nested dictionary, just take the value from `b`
+ merged[key] = value
+ return merged
+
+
def generate_env_vars_recursively(
data: Union[Dict, List],
export_path: List[str],
) -> Dict:
"""Generate environment variables recursively."""
- env_var_dict = {}
+ env_var_dict: Dict[str, Any] = {}
if isinstance(data, dict):
for key, value in data.items():
- env_var_dict.update(
- generate_env_vars_recursively(
- data=value,
- export_path=[*export_path, key],
- )
+ res = generate_env_vars_recursively(
+ data=value,
+ export_path=[*export_path, key],
)
+ if res:
+ env_var = list(res.keys())[0]
+ if env_var in env_var_dict:
+ dicts = (ensure_dict(dict_) for dict_ in (env_var_dict, res))
+ res = ensure_json_content(merge_dicts(*dicts))
+ env_var_dict.update(res)
elif isinstance(data, list):
if is_strict_list(data=data):
- env_var_dict[
- export_path_to_env_var_string(export_path=export_path)
- ] = json.dumps(data, separators=(",", ":"))
+ restricted, path = export_path_to_env_var_string(export_path=export_path)
+ if restricted:
+ env_var_dict[path] = json.dumps(list_to_nested_dict(restricted, data))
+ else:
+ env_var_dict[path] = json.dumps(data, separators=(",", ":"))
else:
for key, value in enumerate(data):
- env_var_dict.update(
- generate_env_vars_recursively(
- data=value,
- export_path=[*export_path, key],
- )
+ res = generate_env_vars_recursively(
+ data=value,
+ export_path=[*export_path, key],
)
+ env_var_dict.update(res)
else:
- env_var_dict[export_path_to_env_var_string(export_path=export_path)] = data
+ restricted, path = export_path_to_env_var_string(export_path=export_path)
+ if restricted:
+ env_var_dict[path] = json.dumps(list_to_nested_dict(restricted, data))
+ else:
+ env_var_dict[path] = data
return env_var_dict
diff --git a/deploy-image/Dockerfile b/deploy-image/Dockerfile
index ac0eead0b2..85308e6d7f 100644
--- a/deploy-image/Dockerfile
+++ b/deploy-image/Dockerfile
@@ -16,7 +16,7 @@ RUN apk add --no-cache go
# aea installation
RUN pip install --upgrade pip
-RUN pip install --upgrade --force-reinstall open-aea[all]==1.57.0 "open-aea-cli-ipfs<2.0.0,>=1.57.0"
+RUN pip install --upgrade --force-reinstall open-aea[all]==1.58.0 "open-aea-cli-ipfs<2.0.0,>=1.58.0"
# directories and aea cli config
WORKDIR /home/agents
diff --git a/deploy-image/README.md b/deploy-image/README.md
index 4e97bc4379..124a18d0ba 100644
--- a/deploy-image/README.md
+++ b/deploy-image/README.md
@@ -11,7 +11,7 @@ The example uses the `fetchai/my_first_aea` project. You will likely want to mod
Install subversion, then download the example directory to your local working directory
``` bash
-svn checkout https://github.com/valory-xyz/open-aea/tags/v1.57.0/packages packages
+svn checkout https://github.com/valory-xyz/open-aea/tags/v1.58.0/packages packages
```
### Modify scripts
diff --git a/develop-image/docker-env.sh b/develop-image/docker-env.sh
index fe2873d9c8..6951406d11 100755
--- a/develop-image/docker-env.sh
+++ b/develop-image/docker-env.sh
@@ -1,7 +1,7 @@
#!/bin/bash
# Swap the following lines if you want to work with 'latest'
-DOCKER_IMAGE_TAG=valory/open-aea-develop:1.57.0
+DOCKER_IMAGE_TAG=valory/open-aea-develop:1.58.0
# DOCKER_IMAGE_TAG=valory/open-aea-develop:latest
DOCKER_BUILD_CONTEXT_DIR=..
diff --git a/docs/api/helpers/base.md b/docs/api/helpers/base.md
index 64f5247146..64fc16e130 100644
--- a/docs/api/helpers/base.md
+++ b/docs/api/helpers/base.md
@@ -838,3 +838,13 @@ Prepend a path with a prefix, but only if not absolute
the same path if absolute, else the prepended path.
+
+
+#### update`_`nested`_`dict
+
+```python
+def update_nested_dict(dict_: dict, nested_update: dict) -> dict
+```
+
+Update a nested dictionary.
+
diff --git a/docs/api/helpers/env_vars.md b/docs/api/helpers/env_vars.md
index d34e6adb8e..ff0705f7db 100644
--- a/docs/api/helpers/env_vars.md
+++ b/docs/api/helpers/env_vars.md
@@ -14,15 +14,26 @@ def is_env_variable(value: Any) -> bool
Check is variable string with env variable pattern.
+
+
+#### restrict`_`model`_`args
+
+```python
+def restrict_model_args(export_path: List[str]) -> Tuple[List[str], List[str]]
+```
+
+Do not allow more levels than one for a model's argument.
+
#### export`_`path`_`to`_`env`_`var`_`string
```python
-def export_path_to_env_var_string(export_path: List[str]) -> str
+def export_path_to_env_var_string(
+ export_path: List[str]) -> Tuple[List[str], str]
```
-Conver export path to environment variable string.
+Convert export path to environment variable string.
@@ -115,6 +126,46 @@ parameters:
Boolean specifying whether it's a strict list or not
+
+
+#### list`_`to`_`nested`_`dict
+
+```python
+def list_to_nested_dict(lst: list, val: Any) -> dict
+```
+
+Convert a list to a nested dict.
+
+
+
+#### ensure`_`dict
+
+```python
+def ensure_dict(dict_: Dict[str, Union[dict, str]]) -> dict
+```
+
+Return the given dictionary converting any values which are json strings as dicts.
+
+
+
+#### ensure`_`json`_`content
+
+```python
+def ensure_json_content(dict_: dict) -> dict
+```
+
+Return the given dictionary converting any nested dictionary values as json strings.
+
+
+
+#### merge`_`dicts
+
+```python
+def merge_dicts(a: dict, b: dict) -> dict
+```
+
+Merge two dictionaries.
+
#### generate`_`env`_`vars`_`recursively
diff --git a/docs/upgrading.md b/docs/upgrading.md
index fd0d368ea2..99e82dd8d1 100644
--- a/docs/upgrading.md
+++ b/docs/upgrading.md
@@ -9,6 +9,10 @@ Below we describe the additional manual steps required to upgrade between differ
### Upgrade guide
+## `v1.57.0` to `v1.58.0`
+
+- No backwards incompatible changes
+
## `v1.56.0` to `v1.57.0`
- No backwards incompatible changes
diff --git a/examples/tac_deploy/Dockerfile b/examples/tac_deploy/Dockerfile
index 294a703361..88a1216780 100644
--- a/examples/tac_deploy/Dockerfile
+++ b/examples/tac_deploy/Dockerfile
@@ -19,7 +19,7 @@ RUN apk add --no-cache go
# aea installation
RUN python -m pip install --upgrade pip
-RUN pip install --upgrade --force-reinstall open-aea[all]==1.57.0
+RUN pip install --upgrade --force-reinstall open-aea[all]==1.58.0
# directories and aea cli config
COPY /.aea /home/.aea
diff --git a/plugins/aea-cli-benchmark/setup.py b/plugins/aea-cli-benchmark/setup.py
index db4f1001c4..6143b38898 100755
--- a/plugins/aea-cli-benchmark/setup.py
+++ b/plugins/aea-cli-benchmark/setup.py
@@ -26,7 +26,7 @@
setup(
name="open-aea-cli-benchmark",
- version="1.57.0",
+ version="1.58.0",
author="Valory AG",
license="Apache-2.0",
description="CLI extension for AEA framework benchmarking.",
diff --git a/plugins/aea-cli-ipfs/setup.py b/plugins/aea-cli-ipfs/setup.py
index 0de1038037..054f1ecc73 100755
--- a/plugins/aea-cli-ipfs/setup.py
+++ b/plugins/aea-cli-ipfs/setup.py
@@ -28,7 +28,7 @@
setup(
name="open-aea-cli-ipfs",
- version="1.57.0",
+ version="1.58.0",
author="Valory AG",
license="Apache-2.0",
description="CLI extension for open AEA framework wrapping IPFS functionality.",
diff --git a/plugins/aea-ledger-cosmos/setup.py b/plugins/aea-ledger-cosmos/setup.py
index ad94811e63..15764e2628 100644
--- a/plugins/aea-ledger-cosmos/setup.py
+++ b/plugins/aea-ledger-cosmos/setup.py
@@ -26,7 +26,7 @@
setup(
name="open-aea-ledger-cosmos",
- version="1.57.0",
+ version="1.58.0",
author="Valory AG",
license="Apache-2.0",
description="Python package wrapping the public and private key cryptography and ledger api of Cosmos.",
diff --git a/plugins/aea-ledger-ethereum-flashbots/setup.py b/plugins/aea-ledger-ethereum-flashbots/setup.py
index 7d54044b20..ac5236e50a 100644
--- a/plugins/aea-ledger-ethereum-flashbots/setup.py
+++ b/plugins/aea-ledger-ethereum-flashbots/setup.py
@@ -25,7 +25,7 @@
setup(
name="open-aea-ledger-ethereum-flashbots",
- version="1.57.0",
+ version="1.58.0",
author="Valory AG",
license="Apache-2.0",
description="Python package extending the default open-aea ethereum ledger plugin to add support for flashbots.",
@@ -41,7 +41,7 @@
},
python_requires=">=3.9,<4.0",
install_requires=[
- "open-aea-ledger-ethereum~=1.57.0",
+ "open-aea-ledger-ethereum~=1.58.0",
"open-aea-flashbots==1.4.0",
],
tests_require=["pytest"],
diff --git a/plugins/aea-ledger-ethereum-hwi/setup.py b/plugins/aea-ledger-ethereum-hwi/setup.py
index 563ca8209e..3726a94213 100644
--- a/plugins/aea-ledger-ethereum-hwi/setup.py
+++ b/plugins/aea-ledger-ethereum-hwi/setup.py
@@ -25,7 +25,7 @@
setup(
name="open-aea-ledger-ethereum-hwi",
- version="1.57.0",
+ version="1.58.0",
author="Valory AG",
license="Apache-2.0",
description="Python package wrapping the public and private key cryptography and support for hardware wallet interactions.",
@@ -42,7 +42,7 @@
"web3>=6.0.0,<7",
"ipfshttpclient==0.8.0a2",
"eth-account>=0.8.0,<0.9.0",
- "open-aea-ledger-ethereum~=1.57.0",
+ "open-aea-ledger-ethereum~=1.58.0",
"ledgerwallet==0.1.3",
"protobuf<4.25.0,>=4.21.6",
"construct<=2.10.61",
diff --git a/plugins/aea-ledger-ethereum/setup.py b/plugins/aea-ledger-ethereum/setup.py
index 8ebeeeeb9f..a5aa034832 100644
--- a/plugins/aea-ledger-ethereum/setup.py
+++ b/plugins/aea-ledger-ethereum/setup.py
@@ -26,7 +26,7 @@
setup(
name="open-aea-ledger-ethereum",
- version="1.57.0",
+ version="1.58.0",
author="Valory AG",
license="Apache-2.0",
description="Python package wrapping the public and private key cryptography and ledger api of Ethereum.",
diff --git a/plugins/aea-ledger-fetchai/setup.py b/plugins/aea-ledger-fetchai/setup.py
index 5197212049..684a2b9386 100644
--- a/plugins/aea-ledger-fetchai/setup.py
+++ b/plugins/aea-ledger-fetchai/setup.py
@@ -31,7 +31,7 @@
setup(
name="open-aea-ledger-fetchai",
- version="1.57.0",
+ version="1.58.0",
author="Valory AG",
license="Apache-2.0",
description="Python package wrapping the public and private key cryptography and ledger API of Fetch.AI.",
@@ -44,7 +44,7 @@
"test_tools/data/*",
]
},
- install_requires=["open-aea-ledger-cosmos~=1.57.0"],
+ install_requires=["open-aea-ledger-cosmos~=1.58.0"],
tests_require=["pytest"],
entry_points={
"aea.cryptos": ["fetchai = aea_ledger_fetchai:FetchAICrypto"],
diff --git a/plugins/aea-ledger-solana/setup.py b/plugins/aea-ledger-solana/setup.py
index 60ac173189..ac05380354 100644
--- a/plugins/aea-ledger-solana/setup.py
+++ b/plugins/aea-ledger-solana/setup.py
@@ -25,7 +25,7 @@
setup(
name="open-aea-ledger-solana",
- version="1.57.0",
+ version="1.58.0",
author="dassy23",
license="Apache-2.0",
description="Python package wrapping the public and private key cryptography and ledger api of solana.",
diff --git a/scripts/install.ps1 b/scripts/install.ps1
index 6627b4ffd2..b09c3a98b1 100644
--- a/scripts/install.ps1
+++ b/scripts/install.ps1
@@ -34,7 +34,7 @@ function instal_choco_golang_gcc {
}
function install_aea {
echo "Install aea"
- $output=pip install open-aea[all]==1.57.0 --force --no-cache-dir 2>&1 |out-string;
+ $output=pip install open-aea[all]==1.58.0 --force --no-cache-dir 2>&1 |out-string;
if ($LastExitCode -ne 0) {
echo $output
echo "AEA install failed!"
diff --git a/scripts/install.sh b/scripts/install.sh
index 74d54160f8..98aa47c211 100755
--- a/scripts/install.sh
+++ b/scripts/install.sh
@@ -42,7 +42,7 @@ function is_python_version_ok() {
function install_aea (){
echo "Install AEA"
- output=$(pip3 install --user open-aea[all]==1.57.0 --force --no-cache-dir)
+ output=$(pip3 install --user open-aea[all]==1.58.0 --force --no-cache-dir)
if [[ $? -ne 0 ]];
then
echo "$output"
diff --git a/skaffold.yaml b/skaffold.yaml
index 37d4fb517f..b67960e240 100644
--- a/skaffold.yaml
+++ b/skaffold.yaml
@@ -5,7 +5,7 @@ metadata:
build:
tagPolicy:
envTemplate:
- template: "1.57.0"
+ template: "1.58.0"
artifacts:
- image: valory/open-aea-develop
docker:
@@ -24,7 +24,7 @@ profiles:
build:
tagPolicy:
envTemplate:
- template: "1.57.0"
+ template: "1.58.0"
artifacts:
- image: valory/open-aea-docs
docker:
diff --git a/tests/test_cli/test_config.py b/tests/test_cli/test_config.py
index e896557c4d..c1aa7971bb 100644
--- a/tests/test_cli/test_config.py
+++ b/tests/test_cli/test_config.py
@@ -462,7 +462,7 @@ def test_set_nested_attribute_not_allowed(self):
assert result.exit_code == 1
assert (
result.exception.message
- == "Attribute `behaviours.dummy.config.behaviour_arg_1` is not allowed to be updated!"
+ == "Attribute `behaviours.dummy.config` is not allowed to be updated!"
)
def test_no_recognized_root(self):
@@ -542,10 +542,11 @@ def test_attribute_not_found(self):
catch_exceptions=False,
)
- def test_set_fails_when_setting_non_primitive_type(self):
+ def test_incorrect_data_type(self):
"""Test that setting the 'dummy' skill behaviours fails because not a primitive type."""
with pytest.raises(
- ClickException, match="Attribute `behaviours` is not allowed to be updated!"
+ ClickException,
+ match="For attribute `behaviours` `dict` data type is expected, but `str` was provided!",
):
self.runner.invoke(
cli,
@@ -558,7 +559,7 @@ def test_get_fails_when_setting_nested_object(self):
"""Test that setting a nested object in 'dummy' skill fails because path is not valid."""
with pytest.raises(
ClickException,
- match=r"Attribute `non_existing_attribute.dummy` is not allowed to be updated!",
+ match=r"Attribute `non_existing_attribute` is not allowed to be updated!",
):
self.runner.invoke(
cli,
diff --git a/tests/test_configurations/test_base.py b/tests/test_configurations/test_base.py
index c2e3336956..27bab57e8c 100644
--- a/tests/test_configurations/test_base.py
+++ b/tests/test_configurations/test_base.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
#
-# Copyright 2022-2023 Valory AG
+# Copyright 2022-2024 Valory AG
# Copyright 2018-2021 Fetch.AI Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -298,7 +298,7 @@ def test_update_method_raises_error_if_skill_component_not_allowed(self):
with pytest.raises(
ValueError,
- match="Attribute `behaviours.new_behaviour.args` is not allowed to be updated!",
+ match="Attribute `behaviours.new_behaviour` is not allowed to be updated!",
):
skill_config.update(new_configurations)
diff --git a/tests/test_configurations/test_validation.py b/tests/test_configurations/test_validation.py
index 1e19a71fab..682be8eba4 100644
--- a/tests/test_configurations/test_validation.py
+++ b/tests/test_configurations/test_validation.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
#
-# Copyright 2022 Valory AG
+# Copyright 2022-2024 Valory AG
# Copyright 2018-2021 Fetch.AI Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -46,14 +46,15 @@ def test_compare_data_pattern():
assert not validate_data_with_pattern(
{"a": "${var}"}, {"a": "string"}, skip_env_vars=True
)
+ assert not validate_data_with_pattern({"a": {}}, {"a": {"b": 12}})
errors = validate_data_with_pattern({"a": 12}, {"b": 12})
assert errors
assert errors[0] == "Attribute `a` is not allowed to be updated!"
- errors = validate_data_with_pattern({"a": {}}, {"a": {"b": 12}})
+ errors = validate_data_with_pattern({"a": {"b": 12}}, {"a": {}})
assert errors
- assert errors[0] == "Attribute `a` is not allowed to be updated!"
+ assert errors[0] == "Attribute `a.b` is not allowed to be updated!"
def test_filter_data():
diff --git a/tests/test_helpers/test_env_vars.py b/tests/test_helpers/test_env_vars.py
index e0fde93864..70a57dd884 100644
--- a/tests/test_helpers/test_env_vars.py
+++ b/tests/test_helpers/test_env_vars.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
#
-# Copyright 2022-2023 Valory AG
+# Copyright 2022-2024 Valory AG
# Copyright 2018-2019 Fetch.AI Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -118,7 +118,7 @@ def test_convert_value_str_to_type():
def test_env_var_string_generator(export_path: List[str], var_string: str) -> None:
"""Test `export_path_to_env_var_string` method"""
- assert export_path_to_env_var_string(export_path=export_path) == var_string
+ assert export_path_to_env_var_string(export_path=export_path)[1] == var_string
@pytest.mark.parametrize(
diff --git a/user-image/Dockerfile b/user-image/Dockerfile
index b15397fbcd..b03227dd60 100644
--- a/user-image/Dockerfile
+++ b/user-image/Dockerfile
@@ -7,7 +7,7 @@ ENV LANG C.UTF-8
RUN apt update && apt install -y python3.11-dev python3-pip -y && apt autoremove && apt autoclean
RUN pip3 install --upgrade pip
-RUN pip3 install "open-aea[all]==1.57.0" open-aea-cli-ipfs==1.57.0
+RUN pip3 install "open-aea[all]==1.58.0" open-aea-cli-ipfs==1.58.0
COPY user-image/openssl.cnf /etc/ssl
diff --git a/user-image/docker-env.sh b/user-image/docker-env.sh
index 98cb1fa9e4..b692f61277 100644
--- a/user-image/docker-env.sh
+++ b/user-image/docker-env.sh
@@ -1,7 +1,7 @@
#!/bin/bash
# Swap the following lines if you want to work with 'latest'
-DOCKER_IMAGE_TAG=valory/open-aea-user:1.57.0
+DOCKER_IMAGE_TAG=valory/open-aea-user:1.58.0
# DOCKER_IMAGE_TAG=valory/open-aea-user:latest
DOCKER_BUILD_CONTEXT_DIR=..