1 """The function in this module you should look to be using is meta_diff"""
5 from __future__
import print_function
10 from PyUtils.MetaReader
import read_metadata, trigger_keys
14 """Create a summary string for an object"""
15 if isinstance(content, str):
20 working_copy = content.items()
21 except AttributeError:
22 working_copy = content
24 for key, value
in working_copy:
27 except (TypeError, ValueError,):
33 return "[{}, {}, ..., {}]".
format(
43 """Create truncted string replaceing dicts with {...}"""
48 '{...}' if isinstance(v, dict)
else v
50 for k, v
in sorted(value.items())
55 def print_diff(parent_key, obj1, obj2, diff_format, filter_key, key_only):
56 """build comparison string for two non-dictionary objects"""
58 if filter_key
is not None and filter_key(parent_key)
is False:
64 if diff_format ==
"simple":
66 result +=
"{} has been inserted".
format(parent_key)
68 result +=
"{} has been deleted".
format(parent_key)
71 result +=
"{} has changed".
format( parent_key )
73 result +=
"{} has changed from '{}' to '{}'".
format(
74 parent_key, obj1, obj2
79 if parent_key
is not None:
82 result +=
"{}".
format(parent_key)
84 result +=
"{}:\n".
format(parent_key)
90 except (AttributeError, TypeError,):
104 """Build diff string for objet of different type"""
106 if filter_key
is not None and filter_key(parent_key)
is False:
112 if diff_format ==
"simple":
114 result +=
"{} has been inserted".
format(parent_key)
116 result +=
"{} has been deleted".
format(parent_key)
120 "{} has changed changed type from {} to {}"
124 "{} has changed changed type from {} (value: '{}') to "
131 if parent_key
is not None:
133 result +=
"{}".
format(parent_key)
135 result +=
"{}:\n".
format(parent_key)
148 """build diff style string for dictionary objects"""
150 if filter_key
is not None and filter_key(parent_key)
is False:
155 if diff_format !=
'simple':
157 for k
in shared_keys:
158 if obj1[k] == obj2[k]:
165 if diff_format ==
'simple':
167 result +=
"{} has been inserted".
format(parent_key)
169 result +=
"{} has been deleted".
format(parent_key)
173 result +=
"{} has changed".
format(parent_key)
177 result +=
"{} has changed from '{}' to '{}'".
format(
178 parent_key, value1, value2
181 if parent_key
is not None:
185 result +=
"{}".
format(parent_key)
187 result +=
"{}:\n".
format(parent_key)
199 def compare(obj1, obj2, parent_key=None, ordered=False, diff_format="simple", filter_key=None, key_only=False):
200 """Caclulate difference between two objects
203 obj1 -- first object in comparision
204 obj2 -- second object in comparision
205 parent_key -- the key of the objects in the parent, used in recursion
206 ordered -- whether to check order of list content
210 if not ordered
and isinstance(obj1, list):
213 if not ordered
and isinstance(obj2, list):
219 if isinstance(obj1,
type(obj2)):
221 if isinstance(obj1, dict):
230 child_key =
"{}/{}".
format(parent_key, key)
234 obj1[key], obj2[key], child_key, ordered, diff_format, filter_key, key_only
238 result += [
print_diff(parent_key, obj1, obj2, diff_format, filter_key, key_only)]
241 result += [
print_diff_type(parent_key, obj1, obj2, diff_format, filter_key, key_only)]
246 def compare_dicts(test, reference, ordered=False, diff_format="simple", filter_key = None, key_only = False):
247 """Show the differences between two dictionaries
250 test (dict): first object in comparision
251 reference (dict): second object in comparision
252 ordered (bool): whether to check order of list content
253 diff_format (string): specify a format to display the difference in
257 keys =
set(test.keys()).union(reference.keys())
265 val2 = reference[key]
274 diff_format=diff_format,
275 filter_key=filter_key,
286 meta_key_filter=None,
289 diff_format="simple",
292 ignore_trigger=False,
295 Compare the in-file metadata in two given files. Uses PyUtils.MetaReader
296 to obtain file content. Generates list of string that show difference.
297 Returns empty list if no difference is found
300 files -- Names of two files to compare
301 verbose -- toggle to get debug information
302 ordered -- whether to check order of lists in the metadata
303 drop -- keys to drop from metadata retrieved by MetaReader
304 mode -- MetaReader argument setting amount of content (default 'lite').
305 Allowed values are: tiny, lite, peeker, and full
306 meta_key_filter -- MetaReader argument selecting keys to retrieve (default
308 file_type -- Type of files, POOL or BS (default: auto-configure)
309 promote -- MetaReader argument (default: False)
310 diff_format -- Return 'simple' or 'diff' style string (default: 'simple')
311 regex -- Use regex for the drop filter (default: False)
312 key_only -- Show only the keys instead of their value (default: False)
315 raise ValueError(
"Wrong number of files passes, need two")
317 reader_msg = logging.getLogger(
"MetaReader")
318 reader_msg.setLevel(logging.INFO
if verbose
else logging.WARNING)
320 msg = logging.getLogger(
"MetaDiff")
321 msg.setLevel(logging.DEBUG
if verbose
else logging.INFO)
323 msg.debug(
"Reading from %s and %s", files[0], files[1])
329 meta_key_filter=meta_key_filter,
333 if drop
is not None and regex:
334 for i
in range(len(drop)):
335 drop[i] = re.compile( drop[i] )
340 for drop_key
in drop:
342 if key.startswith(drop_key):
345 if drop_key.match(key):
349 for trigger_key
in trigger_keys:
350 if key.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 ]))