From b371fd3468b97e34077a509daaec2c7f2a49e4ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Fri, 24 Jun 2022 12:18:36 +0200 Subject: [PATCH] [tools] Fix merge_dicts for d2 immutability --- platform.py | 26 +++++++------------------- tools/util/obj.py | 22 ++++++++++++++-------- tools/util/platform.py | 7 ++----- 3 files changed, 23 insertions(+), 32 deletions(-) diff --git a/platform.py b/platform.py index 26c7062..f0ce0d2 100644 --- a/platform.py +++ b/platform.py @@ -1,6 +1,7 @@ # Copyright (c) Kuba SzczodrzyƄski 2022-04-20. import json +import sys from os.path import dirname, join from typing import Dict @@ -13,6 +14,11 @@ from platformio.package.manager.base import BasePackageManager from platformio.package.meta import PackageItem, PackageSpec from platformio.platform.board import PlatformBoardConfig +# Make tools available +sys.path.insert(0, dirname(__file__)) + +from tools.util.platform import get_board_manifest + libretuya_packages = None manifest_default = {"version": "0.0.0", "description": "", "keywords": []} @@ -174,25 +180,7 @@ class LibretuyaPlatform(PlatformBase): def update_board(self, board: PlatformBoardConfig): if "_base" in board: - base = board.get("_base") - if not isinstance(base, list): - base = [base] - - result = None - for base_name in base: - if base_name not in self.boards_base: - file = join( - dirname(__file__), "boards", "_base", f"{base_name}.json" - ) - with open(file, encoding="utf-8") as f: - self.boards_base[base_name] = json.load(f) - - if not result: - result = self.boards_base[base_name] - else: - util.merge_dicts(result, self.boards_base[base_name]) - util.merge_dicts(result, board._manifest) - board._manifest = result + board._manifest = get_board_manifest(board._manifest) # add "arduino" framework has_arduino = any("arduino" in fw for fw in board.manifest["frameworks"]) diff --git a/tools/util/obj.py b/tools/util/obj.py index f826aea..243887e 100644 --- a/tools/util/obj.py +++ b/tools/util/obj.py @@ -6,14 +6,20 @@ from typing import Tuple, Union SliceLike = Union[slice, str, int] -def merge_dicts(d1, d2, path=None): - if path is None: - path = [] - for key in d2: - if key in d1 and isinstance(d1[key], dict) and isinstance(d2[key], dict): - merge_dicts(d1[key], d2[key], path + [str(key)]) - else: - d1[key] = d2[key] +def merge_dicts(d1, d2): + if d1 is not None and type(d1) != type(d2): + raise TypeError("d1 and d2 are different types") + if isinstance(d2, list): + if d1 is None: + d1 = [] + d1.extend(merge_dicts(None, item) for item in d2) + elif isinstance(d2, dict): + if d1 is None: + d1 = {} + for key in d2: + d1[key] = merge_dicts(d1.get(key, None), d2[key]) + else: + d1 = d2 return d1 diff --git a/tools/util/platform.py b/tools/util/platform.py index 47434e7..2b28cd7 100644 --- a/tools/util/platform.py +++ b/tools/util/platform.py @@ -26,15 +26,12 @@ def get_board_manifest(board: Union[str, dict]) -> dict: base = board["_base"] if not isinstance(base, list): base = [base] - result = None + result = {} for base_name in base: if base_name not in boards_base: file = join(boards_dir, "_base", f"{base_name}.json") boards_base[base_name] = load_json(file) - if not result: - result = boards_base[base_name] - else: - merge_dicts(result, boards_base[base_name]) + merge_dicts(result, boards_base[base_name]) merge_dicts(result, board) board = result return board