-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Move compare_all_but() into a utils file * Eliminate a second loop from the compare_all_but() function. * Rename unused variables from _ to dummy to avoid potential gettext conventions. * rename remove_flatmapping_artefacts() to remove_flatmapping_artifacts() (artefacts is the British English spelling)
- Loading branch information
Showing
2 changed files
with
41 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
# Author: Toshio Kuratomi <[email protected]> | ||
# License: GPLv3+ | ||
# Copyright: Ansible Project, 2020 | ||
"""General functions for working with collections and classes for new data types.""" | ||
"""General functions for working with python collections and classes for new data types.""" | ||
|
||
import typing as t | ||
from collections.abc import Sequence | ||
from collections.abc import Sequence, Set | ||
|
||
|
||
def is_sequence(obj: t.Any, include_string: bool = False) -> bool: | ||
|
@@ -25,3 +25,36 @@ def is_sequence(obj: t.Any, include_string: bool = False) -> bool: | |
if isinstance(obj, Sequence): | ||
return True | ||
return False | ||
|
||
|
||
def compare_all_but(dict_a: t.Mapping, dict_b: t.Mapping, | ||
keys_to_ignore: t.Iterable = None) -> bool: | ||
""" | ||
Compare two dictionaries, with the possibility to ignore some fields. | ||
:arg dict_a: First dictionary to compare | ||
:arg dict_b: Second dictionary to compare | ||
:kwarg keys_to_ignore: An iterable of keys whose values in the dictionaries will not be | ||
compared. | ||
:returns: True if the dictionaries have matching values for all of the keys which were not | ||
ignored. False otherwise. | ||
""" | ||
if keys_to_ignore is None: | ||
return dict_a == dict_b | ||
|
||
if not isinstance(keys_to_ignore, Set): | ||
keys_to_ignore = frozenset(keys_to_ignore) | ||
|
||
length_a = len(frozenset(dict_a.keys()) - keys_to_ignore) | ||
length_b = len(frozenset(dict_b.keys()) - keys_to_ignore) | ||
|
||
if length_a != length_b: | ||
return False | ||
|
||
sentinel = object() | ||
|
||
for key, value in ((k, v) for k, v in dict_a.items() if k not in keys_to_ignore): | ||
if value != dict_b.get(key, sentinel): | ||
return False | ||
|
||
return True |