dgilland / pydash

The kitchen sink of Python utility libraries for doing "stuff" in a functional way. Based on the Lo-Dash Javascript library.

Home Page:http://pydash.readthedocs.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`py_.get()` not compatible with `defaultdict.get()`

larspetrus opened this issue · comments

defaultdict doesn't create entries when .get() is called, but calling pydash.get() does.

This makes using pydash.get() with defaultdicts quite tricky, and I hope the behaviour can be changed.

Hopefully this illustrates the issue well enough:

>>> dd = defaultdict(dict)

>>> dd.get(123)
>>> dd.get(123) is None
True
>>> dd.get(123, "default")
'default'
>>> dd
defaultdict(<class 'dict'>, {})

>>> py_.get(dd, 456)
{}
>>> py_.get(dd, 789, "default")
{}
>>> py_.get(dd, "a.b.c.d", "default")
'default'
>>> dd
defaultdict(<class 'dict'>, {456: {}, 789: {}, 'a': {}})

I wouldn't say that pydash.get was meant to be exactly analogous dict.get even though it functions similarly. Under the hood, it essentially does obj[key] which is why the defaultdict ends up getting populated. This is mainly to support non-dict objects. For pydash.get to function differently for defaultdict, there would likely need to be special type handling to check for it and use a different method to get the value.

Changing pydash.get to handle defaultdict differently would be a breaking change, though, since pydash.get(dd, 123) would return None instead of {}.

Do you have a particular use-case that you want to use pydash.get with defaultdict for? Perhaps there's something else within pydash that might work better?

My use case is that we have a ton of "get chains" like this: message.get("data", {}).get("spectrum_stats", {}).get("start_time"). So I rewrote them to the vastly nicer py_.get(message, "data.spectrum_stats.start_time"), but one test was failing, which led me to understand this difference.

We use regular dicts and defaultdicts interchangeably when reading, so this means we can't really use pydash.get.

I understand if you don't want to deal with a breaking change for this, but I think it would be useful to mention this caveat in the pydash.get documentation.

After some more pondering, I've decided to consider this a bug. Another issue I found was that pydash.has was also populating defaultdicts (due to using pydash.get under the hood) which is not a side-effect that should be happening.

I'll have a bug-fix release soon to fix this.

Fixed in 4.9.1.

Awesome. Thank you!