dgilland / pydash

The kitchen sink of Python utility libraries for doing "stuff" in a functional way. Based on the Lo-Dash Javascript library.
http://pydash.readthedocs.io
MIT License
1.28k stars 89 forks source link

Unexpected difference in path behavior for set_() when accessing attribute of object #213

Closed pveierland closed 5 months ago

pveierland commented 6 months ago

Hello,

Thank you for a great library!

I came across a discrepancy when using the set_ function where using a string path and a list path behaves differently:

❯ python
Python 3.11.6 (main, Oct  2 2023, 13:45:54) [GCC 12.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pydash
>>> pydash.__version__
'7.0.6'
>>> class A:
...     def __init__(self):
...             self.x = {}
...
>>> a = A()
>>> pydash.set_(a, 'x.a.b', 1)
<__main__.A object at 0x7f3e010a17d0>
>>> a.x
{'a': {'b': 1}}
>>> pydash.set_(a, ['x', 'y', 'z'], 1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/venv/lib/python3.11/site-packages/pydash/objects.py", line 1825, in set_
    return set_with(obj, path, value)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venv/lib/python3.11/site-packages/pydash/objects.py", line 1856, in set_with
    return update_with(obj, path, pyd.constant(value), customizer=customizer)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venv/lib/python3.11/site-packages/pydash/objects.py", line 2453, in update_with
    base_set(target, last_key, callit(updater, value))
  File "/venv/lib/python3.11/site-packages/pydash/helpers.py", line 219, in base_set
    key = int(key)
          ^^^^^^^^
ValueError: invalid literal for int() with base 10: 'z'
>>> a.x
{'a': {'b': 1}, 'y': []}

The expected behavior would be for a.x to equal {'a': {'b': 1}, 'y': {'z': 1 }} in the end.

Note that this issue does not occur when accessing e.g. a dict directly:

>>> a = {}
>>> pydash.set_(a, 'x.a.b', 1)
{'x': {'a': {'b': 1}}}
>>> pydash.set_(a, ['x', 'y', 'z'], 1)
{'x': {'a': {'b': 1}, 'y': {'z': 1}}}