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

pydash.set_ does not respect dot escapes

brettdh opened this issue · comments

Demonstration of bug:

Python 3.6.8 (default, Jan  9 2020, 10:08:48) 
[GCC 4.2.1 Compatible Apple LLVM 11.0.0 (clang-1100.0.33.12)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pydash
>>> pydash.__version__
'4.8.0'

>>> pydash.get({'a': {'b.0': {'c': 42}}}, r'a.b\.0.c')
42

>>> pydash.set_({'a': {'b.0': {}}}, r'a.b\.0.c', 42)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/brhiggins/Library/Caches/pypoetry/virtualenvs/pydash-test-i_cQBDIE-py3.6/lib/python3.6/site-packages/pydash/objects.py", line 1206, in set_
    return set_with(obj, path, value)
  File "/Users/brhiggins/Library/Caches/pypoetry/virtualenvs/pydash-test-i_cQBDIE-py3.6/lib/python3.6/site-packages/pydash/objects.py", line 1238, in set_with
    return update_with(obj, path, pyd.constant(value), customizer=customizer)
  File "/Users/brhiggins/Library/Caches/pypoetry/virtualenvs/pydash-test-i_cQBDIE-py3.6/lib/python3.6/site-packages/pydash/objects.py", line 1686, in update_with
    base_set(target, last_key, callit(updater, value))
  File "/Users/brhiggins/Library/Caches/pypoetry/virtualenvs/pydash-test-i_cQBDIE-py3.6/lib/python3.6/site-packages/pydash/helpers.py", line 204, in base_set
    setattr(obj, key, value)
AttributeError: 'NoneType' object has no attribute 'c'

whereas I expected the result to be

{'a': {'b.0': {'c': 42}}}

A list path without the escape fails in a similar manner (this still seems like a bug, but I sort of understand it at least, if each path list element is applied in sequence and the b.0 access returns None):

>>> pydash.set_({'a': {'b.0': {}}}, r'a.b.0.c', 42)
{'a': {'b.0': {}, 'b': {'0': {'c': 42}}}}
>>> pydash.set_({'a': {'b.0': {}}}, ['a', 'b.0', 'c'], 42)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/brhiggins/Library/Caches/pypoetry/virtualenvs/pydash-test-i_cQBDIE-py3.6/lib/python3.6/site-packages/pydash/objects.py", line 1206, in set_
    return set_with(obj, path, value)
  File "/Users/brhiggins/Library/Caches/pypoetry/virtualenvs/pydash-test-i_cQBDIE-py3.6/lib/python3.6/site-packages/pydash/objects.py", line 1238, in set_with
    return update_with(obj, path, pyd.constant(value), customizer=customizer)
  File "/Users/brhiggins/Library/Caches/pypoetry/virtualenvs/pydash-test-i_cQBDIE-py3.6/lib/python3.6/site-packages/pydash/objects.py", line 1686, in update_with
    base_set(target, last_key, callit(updater, value))
  File "/Users/brhiggins/Library/Caches/pypoetry/virtualenvs/pydash-test-i_cQBDIE-py3.6/lib/python3.6/site-packages/pydash/helpers.py", line 204, in base_set
    setattr(obj, key, value)
AttributeError: 'NoneType' object has no attribute 'c'

A list with an escaped string works, but has an undesirable side effect of adding a key that I didn't want:

>>> pydash.set_({'a': {'b.0': {}}}, ['a', r'b\.0', 'c'], 42)
{'a': {'b.0': {'c': 42}, 'b\\.0': {}}}

Also tested with non-numeric elements after the dot:

>>> pydash.set_({'a': {'b.x': {}}}, r'a.b\.x.c', 42)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/brhiggins/Library/Caches/pypoetry/virtualenvs/pydash-test-i_cQBDIE-py3.6/lib/python3.6/site-packages/pydash/objects.py", line 1206, in set_
    return set_with(obj, path, value)
  File "/Users/brhiggins/Library/Caches/pypoetry/virtualenvs/pydash-test-i_cQBDIE-py3.6/lib/python3.6/site-packages/pydash/objects.py", line 1238, in set_with
    return update_with(obj, path, pyd.constant(value), customizer=customizer)
  File "/Users/brhiggins/Library/Caches/pypoetry/virtualenvs/pydash-test-i_cQBDIE-py3.6/lib/python3.6/site-packages/pydash/objects.py", line 1686, in update_with
    base_set(target, last_key, callit(updater, value))
  File "/Users/brhiggins/Library/Caches/pypoetry/virtualenvs/pydash-test-i_cQBDIE-py3.6/lib/python3.6/site-packages/pydash/helpers.py", line 204, in base_set
    setattr(obj, key, value)
AttributeError: 'NoneType' object has no attribute 'c'

I think this was solved in the latest merged PR: #152

Agreed; thanks for the link. I searched issues but didn't think to also search PRs.

@dgilland when do you think a new version could be released?

@brettdh I just released v4.9.0 which includes the fix: https://pypi.org/project/pydash/4.9.0

@dgilland thank you!