From fdce055061324c4f29f29093feb33813db840755 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 18 Mar 2022 06:58:22 +0100 Subject: [PATCH] Update deep_merge_dicts to disallow null-overrides --- freqtrade/misc.py | 6 +++--- tests/test_misc.py | 22 ++++++++++++++++++---- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/freqtrade/misc.py b/freqtrade/misc.py index 534844036..acc7fc2e4 100644 --- a/freqtrade/misc.py +++ b/freqtrade/misc.py @@ -129,7 +129,7 @@ def format_ms_time(date: int) -> str: return datetime.fromtimestamp(date/1000.0).strftime('%Y-%m-%dT%H:%M:%S') -def deep_merge_dicts(source, destination): +def deep_merge_dicts(source, destination, allow_null_overrides: bool = True): """ Values from Source override destination, destination is returned (and modified!!) Sample: @@ -142,8 +142,8 @@ def deep_merge_dicts(source, destination): if isinstance(value, dict): # get node or create one node = destination.setdefault(key, {}) - deep_merge_dicts(value, node) - else: + deep_merge_dicts(value, node, allow_null_overrides) + elif value is not None or allow_null_overrides: destination[key] = value return destination diff --git a/tests/test_misc.py b/tests/test_misc.py index aef7e576b..d28050dfb 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -1,15 +1,16 @@ # pragma pylint: disable=missing-docstring,C0103 import datetime +from copy import deepcopy from pathlib import Path from unittest.mock import MagicMock import pytest -from freqtrade.misc import (decimals_per_coin, file_dump_json, file_load_json, format_ms_time, - pair_to_filename, parse_db_uri_for_logging, plural, render_template, - render_template_with_fallback, round_coin_value, safe_value_fallback, - safe_value_fallback2, shorten_date) +from freqtrade.misc import (decimals_per_coin, deep_merge_dicts, file_dump_json, file_load_json, + format_ms_time, pair_to_filename, parse_db_uri_for_logging, plural, + render_template, render_template_with_fallback, round_coin_value, + safe_value_fallback, safe_value_fallback2, shorten_date) def test_decimals_per_coin(): @@ -203,3 +204,16 @@ def test_render_template_fallback(mocker): def test_parse_db_uri_for_logging(conn_url, expected) -> None: assert parse_db_uri_for_logging(conn_url) == expected + + +def test_deep_merge_dicts(): + a = {'first': {'rows': {'pass': 'dog', 'number': '1', 'test': None}}} + b = {'first': {'rows': {'fail': 'cat', 'number': '5', 'test': 'asdf'}}} + res = {'first': {'rows': {'pass': 'dog', 'fail': 'cat', 'number': '5', 'test': 'asdf'}}} + res2 = {'first': {'rows': {'pass': 'dog', 'fail': 'cat', 'number': '1', 'test': None}}} + assert deep_merge_dicts(b, deepcopy(a)) == res + + assert deep_merge_dicts(a, deepcopy(b)) == res2 + + res2['first']['rows']['test'] = 'asdf' + assert deep_merge_dicts(a, deepcopy(b), allow_null_overrides=False) == res2