Skip to content

Commit

Permalink
diff: fix for unicode keys
Browse files Browse the repository at this point in the history
* Fixes exception when dict has unicode keys and ignore parameter is
  provided.  (closes #50)

Signed-off-by: Jiri Kuncar <jiri.kuncar@cern.ch>
  • Loading branch information
jirikuncar committed Mar 10, 2015
1 parent 855709d commit eeab761
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 4 deletions.
14 changes: 11 additions & 3 deletions dictdiffer/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This file is part of Dictdiffer.
#
# Copyright (C) 2013 Fatih Erikli.
# Copyright (C) 2013, 2014 CERN.
# Copyright (C) 2013, 2014, 2015 CERN.
#
# Dictdiffer is free software; you can redistribute it and/or modify
# it under the terms of the MIT License; see LICENSE file for more
Expand All @@ -16,8 +16,12 @@

if sys.version_info[0] == 3: # pragma: no cover (Python 2/3 specific code)
string_types = str,
text_type = str
PY2 = False
else: # pragma: no cover (Python 2/3 specific code)
string_types = basestring,
text_type = unicode
PY2 = True

(ADD, REMOVE, CHANGE) = (
'add', 'remove', 'change')
Expand Down Expand Up @@ -54,9 +58,13 @@ def diff(first, second, node=None, ignore=None):
# dictionaries are not hashable, we can't use sets
def check(key):
"""Test if key in current node should be ignored."""
if PY2 and isinstance(key, text_type):
new_key = key.encode('utf-8')
else:
new_key = key
return ignore is None \
or (dotted_node + [key] if isinstance(dotted_node, list)
else '.'.join(node + [str(key)])) not in ignore
or (node + [key] if isinstance(dotted_node, list)
else '.'.join(node + [str(new_key)])) not in ignore

intersection = [k for k in first if k in second and check(k)]
addition = [k for k in second if k not in first and check(k)]
Expand Down
14 changes: 13 additions & 1 deletion tests/test_dictdiffer.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# -*- coding: utf-8 -*-
#
# This file is part of Dictdiffer.
#
# Copyright (C) 2013 Fatih Erikli.
# Copyright (C) 2013, 2014 CERN.
# Copyright (C) 2013, 2014, 2015 CERN.
#
# Dictdiffer is free software; you can redistribute it and/or modify
# it under the terms of the MIT License; see LICENSE file for more
Expand Down Expand Up @@ -94,6 +96,16 @@ def test_types(self):
diffed = next(diff(first, second))
assert ('change', 'a', (['a'], 'a')) == diffed

def test_unicode_keys(self):
first = {u'привет': 1}
second = {'hello': 1}
diffed = list(diff(first, second))
assert ('add', '', [('hello', 1)]) in diffed
assert ('remove', '', [(u'привет', 1)]) in diffed

diffed = list(diff(first, second, ignore=['hello']))
assert ('remove', '', [(u'привет', 1)]) == diffed[0]

def test_ignore_key(self):
first = {'a': 'a', 'b': 'b', 'c': 'c'}
second = {'a': 'a', 'b': 2, 'c': 3}
Expand Down

0 comments on commit eeab761

Please sign in to comment.