ATLAS Offline Software
Loading...
Searching...
No Matches
python.MetaDiff Namespace Reference

Functions

 summary (content)
 truncateDict (value)
 print_diff (parent_key, obj1, obj2, diff_format, filter_key, key_only)
 print_diff_type (parent_key, obj1, obj2, diff_format, filter_key, key_only)
 print_diff_dict_keys (parent_key, obj1, obj2, diff_format, filter_key, key_only)
 compare (obj1, obj2, parent_key=None, ordered=False, diff_format="simple", filter_key=None, filter_metadata_items=None, key_only=False)
 compare_dicts (test, reference, ordered=False, diff_format="simple", filter_key=None, filter_metadata_items=None, key_only=False)
 meta_diff (files, verbose=False, ordered=False, drop=None, mode="lite", meta_key_filter=None, file_type=None, promote=False, diff_format="simple", regex=False, key_only=False, ignore_trigger=False)

Detailed Description

The function in this module you should look to be using is meta_diff

Function Documentation

◆ compare()

python.MetaDiff.compare ( obj1,
obj2,
parent_key = None,
ordered = False,
diff_format = "simple",
filter_key = None,
filter_metadata_items = None,
key_only = False )
Caclulate difference between two objects

Keyword arguments:
obj1       -- first object in comparision
obj2       -- second object in comparision
parent_key -- the key of the objects in the parent, used in recursion
ordered    -- whether to check order of list content

Definition at line 198 of file MetaDiff.py.

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
200
201 Keyword arguments:
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
206 """
207 result = list()
208
209 if not ordered and isinstance(obj1, list):
210 obj1.sort()
211
212 if not ordered and isinstance(obj2, list):
213 obj2.sort()
214
215 if obj1 == obj2:
216 return result
217
218 if isinstance(obj1, type(obj2)):
219
220 if isinstance(obj1, dict):
221 # filter out ignored metadata items
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:
225 obj1.pop(key, None)
226 obj2.pop(key, None)
227
228 if sorted(obj1.keys()) != sorted(obj2.keys()):
229 result += [
230 print_diff_dict_keys(parent_key, obj1, obj2, diff_format, filter_key, key_only)
231 ]
232 else:
233 for key in sorted(set(obj1.keys()) | set(obj2.keys())):
234 if parent_key:
235 child_key = "{}/{}".format(parent_key, key)
236 else:
237 child_key = key
238 result += compare(
239 obj1[key], obj2[key], child_key, ordered, diff_format, filter_key, filter_metadata_items, key_only
240 )
241
242 else:
243 result += [print_diff(parent_key, obj1, obj2, diff_format, filter_key, key_only)]
244
245 else:
246 result += [print_diff_type(parent_key, obj1, obj2, diff_format, filter_key, key_only)]
247
248 return result
249
250
STL class.

◆ compare_dicts()

python.MetaDiff.compare_dicts ( test,
reference,
ordered = False,
diff_format = "simple",
filter_key = None,
filter_metadata_items = None,
key_only = False )
Show the differences between two dictionaries

Args:
    test          (dict): first object in comparision
    reference     (dict): second object in comparision
    ordered       (bool): whether to check order of list content
    diff_format (string): specify a format to display the difference in

Definition at line 251 of file MetaDiff.py.

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
253
254 Args:
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
259 """
260 result = list()
261
262 keys = set(test.keys()).union(reference.keys())
263 for key in keys:
264
265 try:
266 val1 = test[key]
267 except KeyError:
268 val1 = None
269 try:
270 val2 = reference[key]
271 except KeyError:
272 val2 = None
273
274 result += compare(
275 obj1=val1,
276 obj2=val2,
277 parent_key=key,
278 ordered=ordered,
279 diff_format=diff_format,
280 filter_key=filter_key,
281 filter_metadata_items=filter_metadata_items,
282 key_only=key_only
283 )
284 return result
285

◆ meta_diff()

python.MetaDiff.meta_diff ( files,
verbose = False,
ordered = False,
drop = None,
mode = "lite",
meta_key_filter = None,
file_type = None,
promote = False,
diff_format = "simple",
regex = False,
key_only = False,
ignore_trigger = False )
Compare the in-file metadata in two given files. Uses PyUtils.MetaReader
to obtain file content. Generates list of string that show difference.
Returns empty list if no difference is found

Keyword arguments:
files   -- Names of two files to compare
verbose -- toggle to get debug information
ordered -- whether to check order of lists in the metadata
drop    -- keys to drop from metadata retrieved by MetaReader
mode    -- MetaReader argument setting amount of content (default 'lite').
           Allowed values are: tiny, lite, peeker, and full
meta_key_filter -- MetaReader argument selecting keys to retrieve (default
                   get all)
file_type    -- Type of files, POOL or BS (default: auto-configure)
promote      -- MetaReader argument (default: False)
diff_format  -- Return 'simple' or 'diff' style string (default: 'simple')
regex        -- Use regex for the drop filter (default: False)
key_only     -- Show only the keys instead of their value (default: False)

Definition at line 286 of file MetaDiff.py.

299):
300 """
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
304
305 Keyword arguments:
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
313 get all)
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)
319 """
320 if len(files) != 2:
321 raise ValueError("Wrong number of files passes, need two")
322
323 reader_msg = logging.getLogger("MetaReader")
324 reader_msg.setLevel(logging.INFO if verbose else logging.WARNING)
325
326 msg = logging.getLogger("MetaDiff")
327 msg.setLevel(logging.DEBUG if verbose else logging.INFO)
328
329 msg.debug("Reading from %s and %s", files[0], files[1])
330
331 metadata = read_metadata(
332 files,
333 file_type,
334 mode=mode,
335 meta_key_filter=meta_key_filter,
336 promote=promote,
337 )
338
339 if drop is not None and regex:
340 for i in range(len(drop)):
341 drop[i] = re.compile( drop[i] )
342
343 def filter_metadata_items(key):
344 key_str = str(key) # force conversion to plain Python string
345
346 if drop is not None:
347 for drop_key in drop:
348 if not drop_key.startswith("metadata_items/"):
349 continue
350
351 drop_key = drop_key[len("metadata_items/"):]
352
353 if not regex:
354 if key_str.startswith(drop_key):
355 return False
356 else:
357 if drop_key.match(key_str):
358 return False
359
360 return True
361
362 def filter_key(key):
363 key_str = str(key) # force conversion to plain Python string
364
365 if drop is not None:
366 for drop_key in drop:
367 if not regex:
368 if key_str.startswith(drop_key):
369 return False
370 else:
371 if drop_key.match(key_str):
372 return False
373
374 if ignore_trigger:
375 for trigger_key in trigger_keys:
376 if key_str.startswith(trigger_key):
377 return False
378
379 return True
380
381 result = compare_dicts(
382 metadata[files[0]],
383 metadata[files[1]],
384 ordered=ordered,
385 diff_format=diff_format,
386 filter_key=filter_key,
387 filter_metadata_items=filter_metadata_items,
388 key_only=key_only
389 )
390
391 if not result:
392 msg.info("No differences found")
393
394 return list(sorted([r for r in result if r is not None ]))

◆ print_diff()

python.MetaDiff.print_diff ( parent_key,
obj1,
obj2,
diff_format,
filter_key,
key_only )
build comparison string for two non-dictionary objects

Definition at line 54 of file MetaDiff.py.

54def print_diff(parent_key, obj1, obj2, diff_format, filter_key, key_only):
55 """build comparison string for two non-dictionary objects"""
56
57 if filter_key is not None and filter_key(parent_key) is False:
58 # skip this key
59 return
60
61 result = "\n"
62
63 if diff_format == "simple":
64 if not obj1:
65 result += "{} has been inserted".format(parent_key)
66 elif not obj2:
67 result += "{} has been deleted".format(parent_key)
68 else:
69 if key_only:
70 result += "{} has changed".format( parent_key )
71 else:
72 result += "{} has changed from '{}' to '{}'".format(
73 parent_key, obj1, obj2
74 )
75 result += "\n"
76 else:
77
78 if parent_key is not None:
79
80 if key_only:
81 result += "{}".format(parent_key)
82 else:
83 result += "{}:\n".format(parent_key)
84 try:
85 overlap = set(obj1).intersection(set(obj2))
86 for item in overlap:
87 obj1.remove(item)
88 obj2.remove(item)
89 except (AttributeError, TypeError,):
90 pass
91 result += """\
92 < {}
93 ----------
94 > {}
95 """.format(
96 summary(obj1), summary(obj2)
97 )
98
99 return result
100
101
std::vector< std::string > intersection(std::vector< std::string > &v1, std::vector< std::string > &v2)

◆ print_diff_dict_keys()

python.MetaDiff.print_diff_dict_keys ( parent_key,
obj1,
obj2,
diff_format,
filter_key,
key_only )
build diff style string for dictionary objects

Definition at line 146 of file MetaDiff.py.

146def print_diff_dict_keys(parent_key, obj1, obj2, diff_format, filter_key, key_only):
147 """build diff style string for dictionary objects"""
148
149 if filter_key is not None and filter_key(parent_key) is False:
150 # skip this key
151 return
152
153 result = '\n'
154 if diff_format != 'simple':
155 shared_keys = set(obj1.keys()).intersection(obj2.keys())
156 for k in shared_keys:
157 if obj1[k] == obj2[k]:
158 try:
159 obj1.pop(k, None)
160 obj2.pop(k, None)
161 except TypeError:
162 pass
163
164 if diff_format == 'simple':
165 if obj1 is None:
166 result += "{} has been inserted".format(parent_key)
167 elif obj2 is None:
168 result += "{} has been deleted".format(parent_key)
169 else:
170
171 if key_only:
172 result += "{} has changed".format(parent_key)
173 else:
174 value1 = truncateDict(obj1)
175 value2 = truncateDict(obj2)
176 result += "{} has changed from '{}' to '{}'".format(
177 parent_key, value1, value2
178 )
179 else:
180 if parent_key is not None:
181
182
183 if key_only:
184 result += "{}".format(parent_key)
185 else:
186 result += "{}:\n".format(parent_key)
187 result += """\
188 < {}
189 ----------
190 > {}
191 """.format( summary(obj1), summary(obj2) )
192
193 result += "\n"
194
195 return result
196
197

◆ print_diff_type()

python.MetaDiff.print_diff_type ( parent_key,
obj1,
obj2,
diff_format,
filter_key,
key_only )
Build diff string for objet of different type

Definition at line 102 of file MetaDiff.py.

102def print_diff_type(parent_key, obj1, obj2, diff_format, filter_key, key_only):
103 """Build diff string for objet of different type"""
104
105 if filter_key is not None and filter_key(parent_key) is False:
106 # skip this key
107 return
108
109 result = "\n"
110
111 if diff_format == "simple":
112 if obj1 is None:
113 result += "{} has been inserted".format(parent_key)
114 elif obj2 is None:
115 result += "{} has been deleted".format(parent_key)
116 else:
117 if key_only:
118 result += (
119 "{} has changed changed type from {} to {}"
120 ).format(parent_key, type(obj1), type(obj2))
121 else:
122 result += (
123 "{} has changed changed type from {} (value: '{}') to "
124 "{} (value: '{}')"
125 ).format(parent_key,
126 type(obj1), obj1,
127 type(obj2), obj2)
128 result += "\n"
129 else:
130 if parent_key is not None:
131 if key_only:
132 result += "{}".format(parent_key)
133 else:
134 result += "{}:\n".format(parent_key)
135 result += """\
136 < {} (type: {})
137 ----------
138 > {} (type: {})
139 """.format(
140 summary(obj1), type(obj1), summary(obj2), type(obj2)
141 )
142
143 return result
144
145

◆ summary()

python.MetaDiff.summary ( content)
Create a summary string for an object

Definition at line 12 of file MetaDiff.py.

12def summary(content):
13 """Create a summary string for an object"""
14 if isinstance(content, str):
15 return content
16
17 try:
18 try:
19 working_copy = content.items()
20 except AttributeError:
21 working_copy = content
22 result = ''
23 for key, value in working_copy:
24 result += "{}: {}, ".format(key, summary(value))
25 return result
26 except (TypeError, ValueError,):
27 pass
28
29 try:
30 if len(content) < 3:
31 return str(content)
32 return "[{}, {}, ..., {}]".format(
33 summary(content[0]), summary(content[1]), summary(content[-1])
34 )
35 except TypeError:
36 pass
37
38 return str(content)
39
40

◆ truncateDict()

python.MetaDiff.truncateDict ( value)
Create truncted string replaceing dicts with {...}

Definition at line 41 of file MetaDiff.py.

41def truncateDict(value):
42 """Create truncted string replaceing dicts with {...}"""
43 return ', '.join(
44 [
45 '{}: {}'.format(
46 k,
47 '{...}' if isinstance(v, dict) else v
48 )
49 for k, v in sorted(value.items())
50 ]
51 )
52
53