Skip to content

2.0

Compare
Choose a tag to compare
@mewwts mewwts released this 12 Dec 14:14
· 51 commits to master since this release

addict now no longer adds keys when you peek on items! ☄️

This means that it's functionality now differs from defaultdict, where calls to getitem will produce a new entry in the defaultdict. Hence, the following now happens when you peek on an empty key:

from addict import Dict
>>> a = Dict()
>>> a.a 
{}
>>> a
{}

However, calls to setitem works just like before:

>>> a.a = 2
>>> a
{'a': 2}

This is possible because of a new implementation detail. Calls to getitem now still returns a new addict Dict, but this instance have to special keyword arguments __parent and __key supplied to __init__. The __parent argument is meant to hold a reference to the Dict in which we called getitem, and the __key argument refers to the key we were peeking on. When, or rather if, this new Dict instance's setitem method is called, it will also call setitem on it's __parent with the key __key and the value itself. Let me illustrate with an example.

>>> a = Dict()
>>> b = a.b
>>> a
{}
>>> b
{}

Above, both a and b are empty Dicts. But let's see what happens to a when we set an item on b

>>> b.c = 2
>>> b
{'c': 2}
>>> a
{'b': {'c': 2}}

Magic.
You should consider these arguments to __init__ reserved, they will not appear as keys in your Dict, and will cause trouble if used in the wrong way. Example:

>>> a = Dict(__parent=2, __key='a')
>>> a.v = 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mats/dev/mewwts/addict/addict/addict.py", line 28, in __setattr__
    self[name] = value
  File "/Users/mats/dev/mewwts/addict/addict/addict.py", line 39, in __setitem__
    p.__setattr__(key, self)
AttributeError: 'int' object has no attribute 'a'