mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-06-01 22:09:08 -07:00
Cleanup combine_vars
* Dedupe combine_vars() code (removed from VariableManager) * Fix merge_hash algorithm to preserve the type * unittest combine_vars and merge_hash
This commit is contained in:
parent
7fe495d619
commit
aeff960d02
5 changed files with 158 additions and 92 deletions
|
@ -20,39 +20,64 @@ from __future__ import (absolute_import, division, print_function)
|
|||
__metaclass__ = type
|
||||
|
||||
import ast
|
||||
from collections import MutableMapping
|
||||
|
||||
from six import string_types
|
||||
from six import iteritems, string_types
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.parsing.splitter import parse_kv
|
||||
from ansible.utils.unicode import to_unicode
|
||||
|
||||
def _validate_mutable_mappings(a, b):
|
||||
"""
|
||||
Internal convenience function to ensure arguments are MutableMappings
|
||||
|
||||
This checks that all arguments are MutableMappings or raises an error
|
||||
|
||||
:raises AnsibleError: if one of the arguments is not a MutableMapping
|
||||
"""
|
||||
|
||||
# If this becomes generally needed, change the signature to operate on
|
||||
# a variable number of arguments instead.
|
||||
|
||||
if not (isinstance(a, MutableMapping) and isinstance(b, MutableMapping)):
|
||||
raise AnsibleError("failed to combine variables, expected dicts but"
|
||||
" got a '{0}' and a '{1}'".format(
|
||||
a.__class__.__name__, b.__class__.__name__))
|
||||
|
||||
def combine_vars(a, b):
|
||||
"""
|
||||
Return a copy of dictionaries of variables based on configured hash behavior
|
||||
"""
|
||||
|
||||
if C.DEFAULT_HASH_BEHAVIOUR == "merge":
|
||||
return merge_hash(a, b)
|
||||
else:
|
||||
# HASH_BEHAVIOUR == 'replace'
|
||||
_validate_mutable_mappings(a, b)
|
||||
result = a.copy()
|
||||
result.update(b)
|
||||
return result
|
||||
|
||||
def merge_hash(a, b):
|
||||
''' recursively merges hash b into a
|
||||
keys from b take precedence over keys from a '''
|
||||
"""
|
||||
Recursively merges hash b into a so that keys from b take precedence over keys from a
|
||||
"""
|
||||
|
||||
result = {}
|
||||
_validate_mutable_mappings(a, b)
|
||||
result = a.copy()
|
||||
|
||||
for dicts in a, b:
|
||||
# next, iterate over b keys and values
|
||||
for k, v in dicts.iteritems():
|
||||
# if there's already such key in a
|
||||
# and that key contains dict
|
||||
if k in result and isinstance(result[k], dict):
|
||||
# merge those dicts recursively
|
||||
result[k] = merge_hash(a[k], v)
|
||||
else:
|
||||
# otherwise, just copy a value from b to a
|
||||
result[k] = v
|
||||
# next, iterate over b keys and values
|
||||
for k, v in iteritems(b):
|
||||
# if there's already such key in a
|
||||
# and that key contains a MutableMapping
|
||||
if k in result and isinstance(result[k], MutableMapping):
|
||||
# merge those dicts recursively
|
||||
result[k] = merge_hash(result[k], v)
|
||||
else:
|
||||
# otherwise, just copy the value from b to a
|
||||
result[k] = v
|
||||
|
||||
return result
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue