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 7f9e634..1af7d9a 100644 --- a/metadict/metadict.py +++ b/metadict/metadict.py @@ -102,16 +102,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 c1ceeba..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 @@ -148,10 +147,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): @@ -242,6 +253,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) @@ -262,21 +276,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