From b4186d5a98ee522e8743fb57116e97713dfc0f1c Mon Sep 17 00:00:00 2001 From: Lars Hillebrand Date: Thu, 27 Oct 2022 12:31:17 +0200 Subject: [PATCH 1/3] Fix memory map reference bug and remove automatic recursive conversion of newly added dicts to metadicts since it is too slow. User can still do it manually though. --- README.md | 15 +++++++++++++-- metadict/__about__.py | 2 +- metadict/metadict.py | 10 ---------- tests/test_metadict.py | 3 +++ 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 8c5758a..655341b 100644 --- a/README.md +++ b/README.md @@ -81,8 +81,19 @@ $ pip install metadict >> Transformer cfg_dict = cfg.to_dict() - print(type(cfg_dict['models'][0]['name'])) - >> dict + print(type(cfg_dict['models'][0])) + >> + + # Note: Appending a `dict` to a list within a `MetaDict` does not convert the `dict`. + # MetaDict does not overwrite `list` so intercepting `append`. `extend`, etc. is currently not possible. + # Simply wrap the appended or extended `dict` as a `MetaDict`. + cfg.models.append({'name': 'RNN'}) + print(isinstance(cfg.models[-1], MetaDict)) + >> False + + cfg.models.append(MetaDict({'name': 'RNN'})) + print(isinstance(cfg.models[-1], MetaDict)) + >> True ``` - No namespace conflicts with inbuilt methods like `items()`, `update()`, etc. ```python diff --git a/metadict/__about__.py b/metadict/__about__.py index 972aaf2..5366bd8 100644 --- a/metadict/__about__.py +++ b/metadict/__about__.py @@ -1,7 +1,7 @@ import time _this_year = time.strftime("%Y") -__version__ = '0.1.2' +__version__ = '0.1.3' __author__ = 'Lars Hillebrand' __author_email__ = 'hokage555@web.de' __license__ = 'Apache-2.0' diff --git a/metadict/metadict.py b/metadict/metadict.py index 687e2aa..db5d537 100644 --- a/metadict/metadict.py +++ b/metadict/metadict.py @@ -101,16 +101,6 @@ def __getitem__(self, key: KT) -> VT: return self.__missing__(key) raise - # if retrieved value is of builtin sequence type we check whether it contains an object of type Mapping - # (except MetaDict type objects). - # if True we call __setitem__ on the retrieved key-value pair to make sure - # all nested dicts are recursively converted to MetaDict objects. - # this is necessary if e.g. a list type attribute/key is appended by a normal dict object. - # oo dynamically convert the appended dict, we call __setitem__ again before the actual object retrieval. - if isinstance(value, (list, set, tuple)) and MetaDict._contains_mapping(value, ignore=self.__class__): - self[key] = value - value = self._data[key] - return value def __missing__(self, key: KT) -> 'MetaDict': diff --git a/tests/test_metadict.py b/tests/test_metadict.py index 0829b4c..3efa33e 100644 --- a/tests/test_metadict.py +++ b/tests/test_metadict.py @@ -242,6 +242,9 @@ def test_references(config: Dict): def test_append_dict_to_list(config: Dict): cfg = MetaDict(config) cfg.model.append({'type_': 'gru'}) + assert type(cfg.model[-1]) == dict + + cfg.model.append(MetaDict({'type_': 'gru'})) assert isinstance(cfg.model[-1], MetaDict) From 704378b13b748d69dc992aec6139aa9b0b1a9d85 Mon Sep 17 00:00:00 2001 From: Lars Hillebrand Date: Thu, 27 Oct 2022 12:49:57 +0200 Subject: [PATCH 2/3] Update tests. --- tests/test_metadict.py | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/tests/test_metadict.py b/tests/test_metadict.py index bae0fd4..5bf8d0e 100644 --- a/tests/test_metadict.py +++ b/tests/test_metadict.py @@ -148,10 +148,22 @@ def test_contains(config: Dict): assert 'model' in cfg -def test_copy(config: Dict): - cfg = MetaDict(config) - assert copy.copy(cfg) is not cfg - assert cfg.copy() == copy.copy(cfg) +def test_copy(): + cfg = MetaDict(a=1) + cfg2 = cfg.copy() + cfg2.a = 2 + assert cfg.a == 1 + assert cfg2.a == 2 + + +def test_copy_recursive(): + cfg = MetaDict() + cfg2 = MetaDict(a=cfg) + cfg.a = cfg2 + cfg3 = cfg.copy() + assert cfg3.a == cfg2 + assert cfg3.a.a == cfg + assert cfg3.a.a.a == cfg2 def test_str(config: Dict): @@ -265,21 +277,3 @@ def test_warning_protected_key(): ('100', False), (100, False), ((1, 2, 3), False)]) def test_complies_variable_syntax(name: Any, expected: bool): assert complies_variable_syntax(name) == expected - - -def test_copy(): - cfg = MetaDict(a=1) - cfg2 = cfg.copy() - cfg2.a = 2 - assert cfg.a == 1 - assert cfg2.a == 2 - - -def test_copy_recursive(): - cfg = MetaDict() - cfg2 = MetaDict(a=cfg) - cfg.a = cfg2 - cfg3 = cfg.copy() - assert cfg3.a == cfg2 - assert cfg3.a.a == cfg - assert cfg3.a.a.a == cfg2 From b52a71fb7a1a9fb136cef887656d2f3b4f54ac7e Mon Sep 17 00:00:00 2001 From: Lars Hillebrand Date: Thu, 27 Oct 2022 12:57:57 +0200 Subject: [PATCH 3/3] Import cleanup in tests. --- tests/test_metadict.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_metadict.py b/tests/test_metadict.py index 5bf8d0e..0dd9640 100644 --- a/tests/test_metadict.py +++ b/tests/test_metadict.py @@ -1,7 +1,6 @@ -from typing import Dict, List, Tuple, Any -import copy import json import pickle +from typing import Dict, List, Tuple, Any import pytest