Skip to main content

MetaDict is a powerful dict subclass enabling (nested) attribute-style item access/assignment and IDE autocompletion support.

Project description

MetaDict

Enabling dot notation and IDE autocompletion

InstallationFeaturesDocumentationCompetitorsCitation

Python Version PyPI version CircleCI codecov License


MetaDict is designed to behave exactly like a dict while enabling (nested) attribute-style key access/assignment with IDE autocompletion support.

Many libraries claim to do the same, but fail in different ways (see Competitors).

Installation

$ pip install metadict

Features

  • Attribute-style key access and assignment (dot notation) with IDE autocompletion support
    from metadict import MetaDict
    
    cfg = MetaDict()
    cfg.optimizer = 'Adam'
    print(cfg.optimizer)
    >> Adam
    
    autocompletion demo
  • Nested key assignment similar to defaultdict from collections
    cfg = MetaDict(nested_assignment=True)
    cfg.model.type = 'Transformer' 
    print(cfg.model.type)
    >> Transformer
    
    # or restrict nested assignment via context manager
    cfg = MetaDict()
    with cfg.enabling_nested_assignment() as cfg:
        cfg.model.type = 'Transformer'
    cfg.new_model.type = 'MLP'
    >> AttributeError: 'MetaDict' object has no attribute 'new_model'
    
  • Is a dict
    dict_config = {'model': 'Transformer',
                   'optimizer': 'Adam'}    
    cfg = MetaDict(dict_config)
    print(isinstance(cfg, dict))
    >> True
    print(cfg == dict_config)
    >> True
    
  • Inbuilt json support
    import json
    
    cfg = MetaDict({'model': 'Transformer'})
    print(json.loads(json.dumps(cfg)))
    >> {'model': 'Transformer'}
    
  • Recursive conversion to dict
    cfg = MetaDict({'models': [{'name': 'Transformer'}, {'name': 'MLP'}]})
    print(cfg.models[0].name)
    >> Transformer
    
    cfg_dict = cfg.to_dict()
    print(type(cfg_dict['models'][0]))
    >> <class 'dict'>
    
    # 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.
    cfg = MetaDict()
    # Key 'items' is assigned as in a normal dict, but a UserWarning is raised
    cfg.items = [1, 2, 3]
    >> UserWarning: 'MetaDict' object uses 'items' internally. 'items' can only be accessed via `obj['items']`.
    print(cfg)
    >> {'items': [1, 2, 3]}
    print(cfg['items'])
    >> [1, 2, 3]
    
    # But the items method is not overwritten!
    print(cfg.items)
    >> <bound method Mapping.items of {'items': [1, 2, 3]}>
    print(list(cfg.items()))
    >> [('items', [1, 2, 3])]
    
  • References are preserved
    params = [1, 2, 3]    
    cfg = MetaDict({'params': params})
    print(cfg.params is params)
    >> True
    
    model_dict = {'params': params}
    cfg = MetaDict(model=model_dict)
    print(cfg.model.params is params)
    >> True
    
    # Note: dicts are recursively converted to MetaDicts, thus...
    print(cfg.model is model_dict)
    >> False
    print(cfg.model == model_dict)
    >> True
    

Documentation

Check the Test Cases for a complete overview of all MetaDict features.

Competitors

  • Addict
    • No key autocompletion in IDE
    • Nested key assignment cannot be turned off
    • Newly assigned dict objects are not converted to support attribute-style key access
    • Shadows inbuilt type Dict
  • Prodict
    • No key autocompletion in IDE without defining a static schema (similar to dataclass)
    • No recursive conversion of dict objects when embedded in list or other inbuilt iterables
  • AttrDict
    • No key autocompletion in IDE
    • Converts list objects to tuple behind the scenes
  • Munch
    • Inbuilt methods like items(), update(), etc. can be overwritten with obj.items = [1, 2, 3]
    • No recursive conversion of dict objects when embedded in list or other inbuilt iterables
  • EasyDict
    • Only strings are valid keys, but dict accepts all hashable objects as keys
    • Inbuilt methods like items(), update(), etc. can be overwritten with obj.items = [1, 2, 3]
    • Inbuilt methods don't behave as expected: obj.pop('unknown_key', None) raises an AttributeError

Citation

@article{metadict,
  title = {MetaDict - Enabling dot notation and IDE autocompletion},
  author = {Hillebrand, Lars},
  year = {2022},
  publisher = {GitHub},
  journal = {GitHub repository},
  howpublished = {\url{https://github.com/LarsHill/metadict}},
}

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

metadict-0.1.3.tar.gz (6.8 kB view details)

Uploaded Source

Built Distribution

metadict-0.1.3-py3-none-any.whl (11.1 kB view details)

Uploaded Python 3

File details

Details for the file metadict-0.1.3.tar.gz.

File metadata

  • Download URL: metadict-0.1.3.tar.gz
  • Upload date:
  • Size: 6.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.9.15

File hashes

Hashes for metadict-0.1.3.tar.gz
Algorithm Hash digest
SHA256 9a3164027facef1a1d24412152a8ffe6172446f1306b5ea9774c546459bd3aa7
MD5 2d679cd1996eddb0a086743eaa3e56e0
BLAKE2b-256 647cce388d73ece8963a30cab5cd095e6c5d7410c9027c475ccb424809f95c7b

See more details on using hashes here.

File details

Details for the file metadict-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: metadict-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 11.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.9.15

File hashes

Hashes for metadict-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 177ec84941fac3a18ecfb3b7ac29543826a186568b5f47ad348d6eae38c28c75
MD5 c6d832456eac8f235c4fefe64e5742c8
BLAKE2b-256 c7b5c893b93df898461a814d592b1beab344629297122f1749f9ad114728c528

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page