1 """The function in this module you should look to be using is meta_diff"""
9 from PyUtils.MetaReader
import read_metadata, trigger_keys
13 """Create a summary string for an object"""
14 if isinstance(content, str):
19 working_copy = content.items()
20 except AttributeError:
21 working_copy = content
23 for key, value
in working_copy:
26 except (TypeError, ValueError,):
32 return "[{}, {}, ..., {}]".
format(
42 """Create truncted string replaceing dicts with {...}"""
47 '{...}' if isinstance(v, dict)
else v
49 for k, v
in sorted(value.items())
54 def print_diff(parent_key, obj1, obj2, diff_format, filter_key, key_only):
55 """build comparison string for two non-dictionary objects"""
57 if filter_key
is not None and filter_key(parent_key)
is False:
63 if diff_format ==
"simple":
65 result +=
"{} has been inserted".
format(parent_key)
67 result +=
"{} has been deleted".
format(parent_key)
70 result +=
"{} has changed".
format( parent_key )
72 result +=
"{} has changed from '{}' to '{}'".
format(
73 parent_key, obj1, obj2
78 if parent_key
is not None:
81 result +=
"{}".
format(parent_key)
83 result +=
"{}:\n".
format(parent_key)
89 except (AttributeError, TypeError,):
103 """Build diff string for objet of different type"""
105 if filter_key
is not None and filter_key(parent_key)
is False:
111 if diff_format ==
"simple":
113 result +=
"{} has been inserted".
format(parent_key)
115 result +=
"{} has been deleted".
format(parent_key)
119 "{} has changed changed type from {} to {}"
123 "{} has changed changed type from {} (value: '{}') to "
130 if parent_key
is not None:
132 result +=
"{}".
format(parent_key)
134 result +=
"{}:\n".
format(parent_key)
147 """build diff style string for dictionary objects"""
149 if filter_key
is not None and filter_key(parent_key)
is False:
154 if diff_format !=
'simple':
156 for k
in shared_keys:
157 if obj1[k] == obj2[k]:
164 if diff_format ==
'simple':
166 result +=
"{} has been inserted".
format(parent_key)
168 result +=
"{} has been deleted".
format(parent_key)
172 result +=
"{} has changed".
format(parent_key)
176 result +=
"{} has changed from '{}' to '{}'".
format(
177 parent_key, value1, value2
180 if parent_key
is not None:
184 result +=
"{}".
format(parent_key)
186 result +=
"{}:\n".
format(parent_key)
198 def compare(obj1, obj2, parent_key=None, ordered=False, diff_format="simple", filter_key=None, key_only=False):
199 """Caclulate difference between two objects
202 obj1 -- first object in comparision
203 obj2 -- second object in comparision
204 parent_key -- the key of the objects in the parent, used in recursion
205 ordered -- whether to check order of list content
209 if not ordered
and isinstance(obj1, list):
212 if not ordered
and isinstance(obj2, list):
218 if isinstance(obj1,
type(obj2)):
220 if isinstance(obj1, dict):
229 child_key =
"{}/{}".
format(parent_key, key)
233 obj1[key], obj2[key], child_key, ordered, diff_format, filter_key, key_only
237 result += [
print_diff(parent_key, obj1, obj2, diff_format, filter_key, key_only)]
240 result += [
print_diff_type(parent_key, obj1, obj2, diff_format, filter_key, key_only)]
245 def compare_dicts(test, reference, ordered=False, diff_format="simple", filter_key = None, key_only = False):
246 """Show the differences between two dictionaries
249 test (dict): first object in comparision
250 reference (dict): second object in comparision
251 ordered (bool): whether to check order of list content
252 diff_format (string): specify a format to display the difference in
256 keys =
set(test.keys()).union(reference.keys())
264 val2 = reference[key]
273 diff_format=diff_format,
274 filter_key=filter_key,
285 meta_key_filter=None,
288 diff_format="simple",
291 ignore_trigger=False,
294 Compare the in-file metadata in two given files. Uses PyUtils.MetaReader
295 to obtain file content. Generates list of string that show difference.
296 Returns empty list if no difference is found
299 files -- Names of two files to compare
300 verbose -- toggle to get debug information
301 ordered -- whether to check order of lists in the metadata
302 drop -- keys to drop from metadata retrieved by MetaReader
303 mode -- MetaReader argument setting amount of content (default 'lite').
304 Allowed values are: tiny, lite, peeker, and full
305 meta_key_filter -- MetaReader argument selecting keys to retrieve (default
307 file_type -- Type of files, POOL or BS (default: auto-configure)
308 promote -- MetaReader argument (default: False)
309 diff_format -- Return 'simple' or 'diff' style string (default: 'simple')
310 regex -- Use regex for the drop filter (default: False)
311 key_only -- Show only the keys instead of their value (default: False)
314 raise ValueError(
"Wrong number of files passes, need two")
316 reader_msg = logging.getLogger(
"MetaReader")
317 reader_msg.setLevel(logging.INFO
if verbose
else logging.WARNING)
319 msg = logging.getLogger(
"MetaDiff")
320 msg.setLevel(logging.DEBUG
if verbose
else logging.INFO)
322 msg.debug(
"Reading from %s and %s", files[0], files[1])
328 meta_key_filter=meta_key_filter,
332 if drop
is not None and regex:
333 for i
in range(len(drop)):
334 drop[i] = re.compile( drop[i] )
340 for drop_key
in drop:
342 if key_str.startswith(drop_key):
345 if drop_key.match(key_str):
349 for trigger_key
in trigger_keys:
350 if key_str.startswith(trigger_key):
359 diff_format=diff_format,
360 filter_key=filter_key,
365 msg.info(
"No differences found")
367 return list(
sorted([r
for r
in result
if r
is not None ]))