Metadata-Version: 2.1 Name: diot Version: 0.1.6 Summary: Python dictionary with dot notation. Home-page: https://github.com/pwwang/diot License: MIT Author: pwwang Author-email: pwwang@pwwang.com Requires-Python: >=3.7,<4.0 Classifier: License :: OSI Approved :: MIT License Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Requires-Dist: inflection (>=0.5,<0.6) Project-URL: Repository, https://github.com/pwwang/diot Description-Content-Type: text/markdown ![Logo](https://raw.githubusercontent.com/pwwang/diot/master/logo.png) [![pypi][1]][2] [![tag][3]][4] [![codacy quality][7]][8] [![coverage][9]][8] ![pyver][10] ![building][6] ![docs][5] Python dictionary with dot notation (A re-implementation of [python-box](https://github.com/cdgriffith/Box) with some issues fixed and simplified) ```python from diot import Diot movie_data = { "movies": { "Spaceballs": { "imdb stars": 7.1, "rating": "PG", "length": 96, "director": "Mel Brooks", "stars": [{"name": "Mel Brooks", "imdb": "nm0000316", "role": "President Skroob"}, {"name": "John Candy","imdb": "nm0001006", "role": "Barf"}, {"name": "Rick Moranis", "imdb": "nm0001548", "role": "Dark Helmet"} ] }, "Robin Hood: Men in Tights": { "imdb stars": 6.7, "rating": "PG-13", "length": 104, "director": "Mel Brooks", "stars": [ {"name": "Cary Elwes", "imdb": "nm0000144", "role": "Robin Hood"}, {"name": "Richard Lewis", "imdb": "nm0507659", "role": "Prince John"}, {"name": "Roger Rees", "imdb": "nm0715953", "role": "Sheriff of Rottingham"}, {"name": "Amy Yasbeck", "imdb": "nm0001865", "role": "Marian"} ] } } } # Box is a conversion_box by default, pass in `conversion_box=False` to disable that behavior # Explicitly tell Diot to convert dict/list inside movie_diot = Diot(movie_data) movie_diot.movies.Robin_Hood_Men_in_Tights.imdb_stars # 6.7 movie_diot.movies.Spaceballs.stars[0].name # 'Mel Brooks' # Different as box, you have to use Diot for new data in a list movie_diot.movies.Spaceballs.stars.append( Diot({"name": "Bill Pullman", "imdb": "nm0000597", "role": "Lone Starr"})) movie_diot.movies.Spaceballs.stars[-1].role # 'Lone Starr' ``` ## Install ```shell pip install -U diot ``` ## API https://pwwang.github.io/diot/api/diot/ ## Usage ### Diot Instantiated the same ways as `dict` ```python Diot({'data': 2, 'count': 5}) Diot(data=2, count=5) Diot({'data': 2, 'count': 1}, count=5) Diot([('data', 2), ('count', 5)]) # All will create # Diot([('data', 2), ('count', 5)], diot_nest = True, diot_transform = 'safe') ``` Same as `python-box`, `Diot` is a subclass of dict which overrides some base functionality to make sure everything stored in the dict can be accessed as an attribute or key value. ```python diot = Diot({'data': 2, 'count': 5}) diot.data == diot['data'] == getattr(diot, 'data') ``` By default, diot uses a safe transformation to transform keys into safe names that can be accessed by `diot.xxx` ```python dt = Diot({"321 Is a terrible Key!": "yes, really"}) dt._321_Is_a_terrible_Key_ # 'yes, really' ``` Different as `python-box`, duplicate attributes are not allowed. ```python dt = Diot({"!bad!key!": "yes, really", ".bad.key.": "no doubt"}) # KeyError ``` Use different transform functions: ```python dt = Diot(oneTwo = 12, diot_transform = 'snake_case') # or use alias: # dt = SnakeDiot(oneTwo = 12) dt.one_two == dt['one_two'] == dt['oneTwo'] == 12 dt = Diot(one_two = 12, diot_transform = 'camel_case') # or use alias: # dt = CamelDiot(one_two = 12) dt.oneTwo == dt['one_two'] == dt['oneTwo'] == 12 dt = Diot(one_two = 12, diot_transform = 'upper') dt.ONE_TWO == dt['one_two'] == dt['ONETWO'] == 12 dt = Diot(ONE_TWO = 12, diot_transform = 'lower') dt.one_two == dt['ONE_TWO'] == dt['one_two'] == 12 ``` Use your own transform function: ```python import inflection dt = Diot(post = 10, diot_transform = inflection.pluralize) dt.posts == dt['posts'] == dt['post'] == 10 ``` ### OrderedDiot ```python diot_of_order = OrderedDiot() diot_of_order.c = 1 diot_of_order.a = 2 diot_of_order.d = 3 list(diot_of_order.keys()) == ['c', 'a', 'd'] # insertion allowed for OrderedDiot od = OrderedDiot() od.insert(0, "c", "d") od.insert(None, "x", "y") od.insert_before('c', "e", "f") od.insert_after("a", ("g", "h")) od2 = OrderedDiot() od2.a1 = 'b1' od2.c1 = 'd1' od.insert(-1, od2) od3 = OrderedDiot() od3.a2 = 'b2' od3.c2 = 'd2' od.insert_before('c', od3) ``` ### FrozenDiot ```python fd = FrozenDiot(a=1, b=3) fd.c = 3 # DiotFrozenError with fd.thaw(): fd.c = 3 fd.c == 3 ``` ### Missing key handler ```python d = Diot(a=1, b=2, diot_missing=ValueError) d['c'] # ValueError d.c # AttributeError from ValueError d = Diot(a=1, b=2, diot_missing=ValueError("Custom message")) d = Diot(a=1, b=2, diot_missing=None) # d.c is None d = Diot(a=1, b=2, diot_missing=lambda key, diot: diot.a + diot.b) # d.c == 3 ``` [1]: https://img.shields.io/pypi/v/diot?style=flat-square [2]: https://pypi.org/project/diot/ [3]: https://img.shields.io/github/tag/pwwang/diot?style=flat-square [4]: https://github.com/pwwang/diot [5]: https://img.shields.io/github/workflow/status/pwwang/diot/Build%20Docs?label=docs&style=flat-square [6]: https://img.shields.io/github/workflow/status/pwwang/diot/Build%20and%20Deploy?style=flat-square [7]: https://img.shields.io/codacy/grade/738e49b9cc1745c4ae6a7bb3b198cc3d?style=flat-square [8]: https://app.codacy.com/gh/pwwang/diot/dashboard [9]: https://img.shields.io/codacy/coverage/738e49b9cc1745c4ae6a7bb3b198cc3d?style=flat-square [10]: https://img.shields.io/pypi/pyversions/diot?style=flat-square