Skip to content

Commit

Permalink
improved json__equals__list_and_set method
Browse files Browse the repository at this point in the history
  • Loading branch information
DinisCruz committed Jan 28, 2025
1 parent 5c1e5fe commit ebf8e21
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 7 deletions.
28 changes: 23 additions & 5 deletions osbot_utils/utils/Json.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,34 @@ def json_dumps(python_object, indent=4, pretty=True, sort_keys=False, default=st
def json_dumps_to_bytes(*args, **kwargs):
return json_dumps(*args, **kwargs).encode()

def json__type_key(obj: Any) -> tuple:
if obj is None : return (0, None)
if isinstance(obj, bool) : return (1, obj)
if isinstance(obj, int) : return (2, obj)
if isinstance(obj, float) : return (3, obj)
if isinstance(obj, str) : return (4, obj)
if isinstance(obj, (list, set, tuple)): return (5, tuple(sorted(json__type_key(x) for x in obj)))
if isinstance(obj, dict) : return (6, tuple(sorted((k, json__type_key(v)) for k,v in obj.items())))
return (7, str(obj)) # Fallback for unknown types

def json__equals__list_and_set(value_1: Any, value_2: Any) -> bool:
if isinstance(value_1, (list, set)) or isinstance(value_2, (list, set)):
list_1 = sorted(list(value_1))
list_2 = sorted(list(value_2))
return list_1 == list_2
list_1 = list(value_1)
list_2 = list(value_2)

if len(list_1) != len(list_2): # Quick length check
return False

sorted_1 = sorted(list_1, key=json__type_key)
sorted_2 = sorted(list_2, key=json__type_key)

return all(json__equals__list_and_set(a, b)
for a, b in zip(sorted_1, sorted_2))

if isinstance(value_1, dict) and isinstance(value_2, dict):
if value_1.keys() != value_2.keys(): # Check keys match
if value_1.keys() != value_2.keys(): # Check keys match
return False
return all(json__equals__list_and_set(value_1[key], value_2[key]) # Recursively compare values
return all(json__equals__list_and_set(value_1[key], value_2[key]) # Recursively compare values
for key in value_1.keys())

return value_1 == value_2
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/helpers/test_Obj_Id.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def test_new_obj_id(self):

def test__perf__new__(self):
with Performance_Measure__Session() as _:
_.measure(lambda: Obj_Id() ).assert_time__less_than(700)
_.measure(lambda: Obj_Id() ).assert_time__less_than(1000)

def test__perf__new_obj_id(self):
with Performance_Measure__Session() as _:
Expand Down
13 changes: 12 additions & 1 deletion tests/unit/utils/test_Json.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from osbot_utils.utils.Json import json_save_tmp_file, json_parse, json_loads, json_dumps, json_format, \
json_load_file, json_load_file_and_delete, json_save_file_pretty_gz, json_load_file_gz, \
json_round_trip, json_load_file_gz_and_delete, json_save_file_pretty, json_save_file, json_load, json_to_gz, \
gz_to_json
gz_to_json, json__equals__list_and_set
from osbot_utils.utils.Misc import list_set
from osbot_utils.utils.Status import send_status_to_logger, osbot_status, osbot_logger
from osbot_utils.utils.Zip import str_to_gz, gz_to_str
Expand Down Expand Up @@ -54,6 +54,17 @@ def test_json_dumps__bad_object(self):
assert type(round_trip.get('date')) is str



def test_json__equals__list_and_set(self):
value_1 = [{'id': 2, 'name': 'second'}, {'id': 1, 'name': 'first'}]
value_2 = [{'id': 1, 'name': 'first' }, {'id': 2, 'name': 'second'}]
assert json__equals__list_and_set(value_1, value_2)

value_1 = ['two', {'three': 3}, [5, 4], 1]
value_2 = [1, 'two', {'three': 3}, [4, 5]]

assert json__equals__list_and_set(value_1, value_2)

def test_json_parse__json_format__json_dumps__json_loads(self):
data = {'answer': 42 }
assert json_dumps (data) == '{\n "answer": 42\n}'
Expand Down

0 comments on commit ebf8e21

Please sign in to comment.