1"""The function in this module you should look to be using is meta_diff"""
9from 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:
24 result +=
"{}: {}, ".format(key,
summary(value))
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())
54def 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 {}"
120 ).format(parent_key,
type(obj1),
type(obj2))
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)
198def compare(obj1, obj2, parent_key=None, ordered=False, diff_format="simple", filter_key=None, filter_metadata_items=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):
222 if parent_key ==
"metadata_items":
223 for key
in set(list(obj1.keys()) + list(obj2.keys())):
224 if filter_metadata_items
is not None and filter_metadata_items(key)
is False:
228 if sorted(obj1.keys()) != sorted(obj2.keys()):
233 for key
in sorted(
set(obj1.keys()) |
set(obj2.keys())):
235 child_key =
"{}/{}".format(parent_key, key)
239 obj1[key], obj2[key], child_key, ordered, diff_format, filter_key, filter_metadata_items, key_only
243 result += [
print_diff(parent_key, obj1, obj2, diff_format, filter_key, key_only)]
246 result += [
print_diff_type(parent_key, obj1, obj2, diff_format, filter_key, key_only)]
251def compare_dicts(test, reference, ordered=False, diff_format="simple", filter_key=None, filter_metadata_items=None, key_only=False):
252 """Show the differences between two dictionaries
255 test (dict): first object in comparision
256 reference (dict): second object in comparision
257 ordered (bool): whether to check order of list content
258 diff_format (string): specify a format to display the difference in
262 keys =
set(test.keys()).union(reference.keys())
270 val2 = reference[key]
279 diff_format=diff_format,
280 filter_key=filter_key,
281 filter_metadata_items=filter_metadata_items,
292 meta_key_filter=None,
295 diff_format="simple",
298 ignore_trigger=False,
301 Compare the in-file metadata in two given files. Uses PyUtils.MetaReader
302 to obtain file content. Generates list of string that show difference.
303 Returns empty list if no difference is found
306 files -- Names of two files to compare
307 verbose -- toggle to get debug information
308 ordered -- whether to check order of lists in the metadata
309 drop -- keys to drop from metadata retrieved by MetaReader
310 mode -- MetaReader argument setting amount of content (default 'lite').
311 Allowed values are: tiny, lite, peeker, and full
312 meta_key_filter -- MetaReader argument selecting keys to retrieve (default
314 file_type -- Type of files, POOL or BS (default: auto-configure)
315 promote -- MetaReader argument (default: False)
316 diff_format -- Return 'simple' or 'diff' style string (default: 'simple')
317 regex -- Use regex for the drop filter (default: False)
318 key_only -- Show only the keys instead of their value (default: False)
321 raise ValueError(
"Wrong number of files passes, need two")
323 reader_msg = logging.getLogger(
"MetaReader")
324 reader_msg.setLevel(logging.INFO
if verbose
else logging.WARNING)
326 msg = logging.getLogger(
"MetaDiff")
327 msg.setLevel(logging.DEBUG
if verbose
else logging.INFO)
329 msg.debug(
"Reading from %s and %s", files[0], files[1])
331 metadata = read_metadata(
335 meta_key_filter=meta_key_filter,
339 if drop
is not None and regex:
340 for i
in range(len(drop)):
341 drop[i] = re.compile( drop[i] )
343 def filter_metadata_items(key):
347 for drop_key
in drop:
348 if not drop_key.startswith(
"metadata_items/"):
351 drop_key = drop_key[len(
"metadata_items/"):]
354 if key_str.startswith(drop_key):
357 if drop_key.match(key_str):
366 for drop_key
in drop:
368 if key_str.startswith(drop_key):
371 if drop_key.match(key_str):
375 for trigger_key
in trigger_keys:
376 if key_str.startswith(trigger_key):
385 diff_format=diff_format,
386 filter_key=filter_key,
387 filter_metadata_items=filter_metadata_items,
392 msg.info(
"No differences found")
394 return list(sorted([r
for r
in result
if r
is not None ]))
std::vector< std::string > intersection(std::vector< std::string > &v1, std::vector< std::string > &v2)