Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Cast integer key to str if str key exist in dictionary #167

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

jferreira-ca
Copy link

@jferreira-ca jferreira-ca commented Nov 22, 2022

Fix for issue where we have a numeric key in dictionary that is a string, and dpath.util.new creates the same numeric key but as an integer.

Actual Result:

a = {"root": {"1": {"k": "v"}}}
dpath.util.new(a, "root/1/k", "new")

Out[6]: {'root': {'1': {'k': 'v'}, 1: {'k': 'new'}}}

Expected Result:

a = {"root": {"1": {"k": "v"}}}
dpath.util.new(a, "root/1/k", "new")

Out[6]: {'root': {'1': {'k': 'new'}}

@moomoohk
Copy link
Collaborator

Hi @jferreira-ca
Thanks for the PR.
I've updated the tests on the master branch so they shouldn't fail again for the same reason (flake8 related).
Please pull from master and bump your version.
Thanks

@jferreira-ca
Copy link
Author

thanks @moomoohk.

@moomoohk
Copy link
Collaborator

I've gone over your change and I'm not sure this patch is needed.

While debugging the set function I discovered that the segments variable is set to: ['root', 1, 'k'] where you're obviously expecting it to be: ['root', '1', 'k'].

So I checked and the segments variable is created in the new function by calling the __safe_path__ function (util.py:62).

In the __safe_path__ function you'll find the path parser which also contains code to convert int-like segments to int objects. Your suggested patch ultimately undoes that action.

Instead of doing that, you could set dpath.options.CONVERT_INT_LIKE_SEGMENTS to False. This will disable the conversion code in the path parser.

Please let me know if this proposal solves your issue.

@jferreira-ca
Copy link
Author

jferreira-ca commented Nov 23, 2022

It worked. Thanks for your support on that. I think we can close this PR then.

@jferreira-ca
Copy link
Author

jferreira-ca commented Nov 23, 2022

sorry about that @moomoohk. I'm reopening it. The option works well if we are not using lists. But for our scenario we're using nested dicts and lists all together, on this case if we use that option it'll cause a TypeError.

Example:
imagine I want to change this nested dict in the first element on the list: {"list": [{"root": {"1": {"k": None}}}]}
like: dpath.util.new(a, "list/0/root/1/k", "new")

actual:
TypeError: list indices must be integers or slices, not str

expected:
{"list": [{"root": {"1": {"k": "new"}}}]}

@moomoohk
Copy link
Collaborator

I believe that problem can be overcome by using a custom creator function and passing it using the creator kwarg.

Please refer to this comment (the code there doesn't work in your specific case).

@moomoohk
Copy link
Collaborator

Hi @jferreira-ca,
I'm currently working on a major refactor to this project. Among other changes I've better documented the creator feature.
In case you'd like to have a look, here is the relevant code on the refactor branch: https://github.com/dpath-maintainers/dpath-python/blob/feature/refactor/dpath/types.py#L29

@jferreira-ca
Copy link
Author

Hey @moomoohk thanks for the response. Before open this PR we actually tested passing a new creator function, but for this scenario specifically it does not work.

@moomoohk
Copy link
Collaborator

Could you please include some example code? (The creator that failed)

@jferreira-ca
Copy link
Author

Even passing a creator the code still breaks cause segments.set function still tries to access the node using the int key.

@moomoohk
Copy link
Collaborator

@jferreira-ca I've pushed a small change to the branch bugfix/bad-type-check. Please try passing your creator on that branch and let me know if it works.

@jferreira-ca
Copy link
Author

jferreira-ca commented Nov 29, 2022

Honestly I don't understand how a creator could help on this case. The problem happens when a dict has ant int key on it as str (e.g "1": {}. Note it's not 1: {})

@moomoohk moomoohk mentioned this pull request Nov 29, 2022
@moomoohk
Copy link
Collaborator

@jferreira-ca I've identified the issue. Please follow #169 for updates.

I'm closing this PR.

Regards.

@moomoohk moomoohk closed this Nov 29, 2022
@jferreira-ca
Copy link
Author

thanks!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants