Created
June 17, 2011 17:25
-
-
Save solex/1031841 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import json | |
from json.decoder import JSONArray | |
from json.scanner import py_make_scanner | |
class UnorderedList(list): | |
""" | |
Works like a normal list, except the order of elements doesn't matter on | |
comparison | |
>>> UnorderedList([1, 2, 3]) == UnorderedList([3, 1, 2]) | |
True | |
>>> UnorderedList([1, 2, 3]) == UnorderedList([3, 1, 2, 2]) | |
False | |
""" | |
def __eq__(self, other): | |
if isinstance(other, type(self)): | |
return sorted(self) == sorted(other) | |
else: | |
return False | |
def __repr__(self): | |
return "UnorderedList(%s)" % super(UnorderedList, self).__repr__() | |
def custom_parse_array(*args, **kwargs): | |
values, end = JSONArray(*args, **kwargs) | |
return UnorderedList(values), end | |
class CustomJSONDecoder(json.JSONDecoder): | |
""" | |
Custom decoder that reresents JSON arrays as UnorderedLists. | |
Doesn't use C extensions, so possibly slower than the built-in decoder | |
>>> json.loads('[1, 2, 3, [4, 5, 6]]', cls=CustomJSONDecoder) | |
UnorderedList([1, 2, 3, UnorderedList([4, 5, 6])]) | |
>>> l1 = json.loads('[1, 2, 3, [4, 5, 6]]', cls=CustomJSONDecoder) | |
>>> l2 = json.loads('[1, [6, 5, 4], 3, 2]', cls=CustomJSONDecoder) | |
>>> l1 == l2 | |
True | |
>>> l1 = json.loads('[1, 2, 3, [4, 5, 6, 7]]', cls=CustomJSONDecoder) | |
>>> l2 = json.loads('[1, [6, 5, 4], 3, 2]', cls=CustomJSONDecoder) | |
>>> l1 == l2 | |
False | |
>>> l1 = json.loads('{"foo": [1, 2, 3], "bar": 42}', cls=CustomJSONDecoder) | |
>>> l2 = json.loads('{"foo": [3, 2, 1], "bar": 42}', cls=CustomJSONDecoder) | |
>>> l1 == l2 | |
True | |
""" | |
def __init__(self, *args, **kwargs): | |
super(CustomJSONDecoder, self).__init__(*args, **kwargs) | |
self.parse_array = custom_parse_array | |
self.scan_once = py_make_scanner(self) | |
if __name__ == '__main__': | |
import doctest | |
doctest.testmod() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment