gmr / flatdict

Python module for interacting with nested dicts as a single level dict with delimited keys.
https://flatdict.readthedocs.io
BSD 3-Clause "New" or "Revised" License
111 stars 32 forks source link

Cast as dict will return an empty dict #15

Closed gabisurita closed 6 years ago

gabisurita commented 6 years ago

Casting as such will fail.

>>> d = flatdict.FlatterDict({'a': {'b': ['c', 'd']}})
>>> dict(d)
{}
>>> {**d}  # Py3 Only
{}

The same happens if you try to use it as keyword arguments.

>>> def foo(**a):
...:     print(a)

>>> foo(d)
{}
gmr commented 6 years ago

As of right this moment, I'm not expecting this to work, and rather that the as_dict methods are called.

The issue here that implementing FlatDict.__iter__ should behave like a dict.__iter__ which is as follows:

Python 2.7.10 (default, Jul 15 2017, 17:16:57) 
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pprint
>>> a = {'a': 1, 'b': 2, 'c': 3}
>>> for item in a:
...     pprint.pprint(item)
... 
'a'
'c'
'b'

To enable direct casting to dict, the FlatDict.__iter__ method would need to work like dict.iteritems or FlatDict.iteritems:

for item in a.iteritems(): ... pprint.pprint(item) ... ('a', 1) ('c', 3) ('b', 2)

Which would allow you to cast directly, for example you could do:

Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 26 2016, 10:47:25) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import flatdict
>>> d = flatdict.FlatterDict({'a': {'b': ['c', 'd']}})
>>> dict(d.iteritems())
{'a:b:0': 'c', 'a:b:1': 'd'}

Or even:

>>> d.as_dict()
{'a:b': ['c', 'd']}

I'm looking into what magical voodoo allows dict.iter to behave as it does for iterating keys only, and yet still work correctly when being invoked by dict(dict_val).

gmr commented 6 years ago

Implemented dict() casting for 3.0 which will return the values as shallow keys:

Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 26 2016, 10:47:25) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import flatdict
>>> a = flatdict.FlatDict({'a': {'b': 'c', 'd': 'e', 'f': {'g': 'h'}}})
>>> dict(a)
{'a:d': 'e', 'a:f:g': 'h', 'a:b': 'c'}
gmr commented 6 years ago

3.0 released with this enhancement. Thanks for opening the issue!