Skip to content
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

Can't compare dicts with both single and double quotes in keys #430

Closed
kammala opened this issue Nov 8, 2023 · 3 comments
Closed

Can't compare dicts with both single and double quotes in keys #430

kammala opened this issue Nov 8, 2023 · 3 comments
Assignees

Comments

@kammala
Copy link

kammala commented Nov 8, 2023

Describe the bug
DeepDiff falls with an exception while comparing dicts with keys containing both single and double quotes.

To Reproduce

import deepdiff

deepdiff.DeepDiff({'''a'"a''': 1}, {'''a'"a''': 2})

Expected behavior
A comparison result is being returned.

OS, DeepDiff version and Python version (please complete the following information):

  • DeepDiff Version: 6.7.0

Additional context
The branch to handle both single and double quotes in stringify_element doesn't define result variable which is used later in return statement which causes exception (UnboundLocalError: local variable 'result' referenced before assignment) to be triggered.

@seperman seperman self-assigned this Nov 14, 2023
@asterbini
Copy link

I get an error on stringify_element when param is a byte string.
With the following change (in the first 2 lines) it works.

def stringify_element(param, quote_str=None):
    if isinstance(param, str):
        has_quote = "'" in param
        has_double_quote = '"' in param
    else:
        has_quote = b"'" in param
        has_double_quote = b'"' in param
    if has_quote and has_double_quote:
        new_param = []
        for char in param:
            if char in {'"', "'"}:
                new_param.append('\\')
            new_param.append(char)
        result = ''.join(new_param)
    elif has_quote:
        result = f'"{param}"'
    elif has_double_quote:
        result = f"'{param}'"
    else:
        result = param if quote_str is None else quote_str.format(param)
    return result

@seperman
Copy link
Owner

seperman commented Nov 15, 2023 via email

@asterbini
Copy link

asterbini commented Nov 15, 2023

I am not so familiar with all the DeepDiff code, thus let me try just suggesting a correction that seems to work assuming one is using 'utf8' encoding in bytes and bytearray

def stringify_element(param, quote_str=None):
    if isinstance(param, (bytes, bytearray)):   ## handle bytes
        param = param.decode('utf8')            ## here
    has_quote = "'" in param
    has_double_quote = '"' in param
    if has_quote and has_double_quote:
        new_param = []
        for char in param:
            if char in {'"', "'"}:
                new_param.append('\\')
            new_param.append(char)
        result = ''.join(new_param)
    elif has_quote:
        result = f'"{param}"'
    elif has_double_quote:
        result = f"'{param}'"
    else:
        result = param if quote_str is None else quote_str.format(param)
    return result

Test:

B = {'Foo\'\"':42}
A = {b'Foo\'\"':42}
deepdiff.DeepDiff(A, B)
Out[8]: 
{'dictionary_item_added': [root[Foo\'\"]],
 'dictionary_item_removed': [root[Foo\'\"]]}

netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this issue Jan 28, 2024
v6-7-1

-  Support for subtracting delta objects when iterable_compare_func
   is used.
-  Better handling of force adding a delta to an object.
-  Fix for
   ```Can't compare dicts with both single and double quotes in keys`` <https://github.com/seperman/deepdiff/issues/430>`__
-  Updated docs for Inconsistent Behavior with math_epsilon and
   ignore_order = True

v6-7-0

-  Delta can be subtracted from other objects now.
-  verify_symmetry is deprecated. Use bidirectional instead.
-  always_include_values flag in Delta can be enabled to include
   values in the delta for every change.
-  Fix for Delta.\__add\_\_ breaks with esoteric dict keys.

v6-6-1

 -  Fix for `DeepDiff raises decimal exception when using significant
    digits <https://github.com/seperman/deepdiff/issues/426>`__
 -  Introducing group_by_sort_key
 -  Adding group_by 2D. For example
    ``group_by=['last_name', 'zip_code']``

v6-6-0

-  Numpy 2.0 support
-  Adding
   `Delta.to_flat_dicts <https://zepworks.com/deepdiff/current/serialization.html#delta-serialize-to-flat-dictionaries>`__

v6-5-0

-  Adding
   ```parse_path`` <https://github.com/seperman/deepdiff/pull/419>`__

v6-4-1

-  Bugfix: Keep Numpy Optional
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

No branches or pull requests

3 participants