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.5.tar.gz (10.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

metadict-0.1.5-py3-none-any.whl (11.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: metadict-0.1.5.tar.gz
  • Upload date:
  • Size: 10.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.23

File hashes

Hashes for metadict-0.1.5.tar.gz
Algorithm Hash digest
SHA256 4ebd972a4bd1d22e72a158bfc6ff8d497deab7ab220fa27ad128fcee4f54f300
MD5 a555cf9d90a1060a31493316b4ee8fa5
BLAKE2b-256 d1e1b1831cf30286259e8250c9ec2814cc27c1110a91437723f85fb5b74138ab

See more details on using hashes here.

File details

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

File metadata

  • Download URL: metadict-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 11.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.23

File hashes

Hashes for metadict-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 e374cf55cd7e182135f35c50f9c4e83b8f0d70e74b626f6c4499a01267ad0f80
MD5 a3ea685bda910bae69d1dfae4dc40fe9
BLAKE2b-256 5b62526f926e3cfbc0cd136480b5902f920502aa41a0c914db3e20ea2804d64c

See more details on using hashes here.

Supported by

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