This library makes it possible to introspect dataset and aggregate nodes when it is instructed.


The following examples with be expressed in YAML for convenience's sake:

  • !aggr-scalar will refer to Scalar python function

  • !aggr-map will refer to Map python object

  • !aggr-seq will refer for Sequence python object

How to instructs merging

This yaml document has duplicate keys:

foo: !aggr-scalar first
foo: !aggr-scalar second
bar: !aggr-map {first: foo}
bar: !aggr-map {second: bar}
baz: !aggr-scalar 42

but tagged values instruct Salt that overlapping values they can be merged together:

foo: !aggr-seq [first, second]
bar: !aggr-map {first: foo, second: bar}
baz: !aggr-seq [42]

Default merge strategy is keep untouched

For example, this yaml document still has duplicate keys, but does not instruct aggregation:

foo: first
foo: second
bar: {first: foo}
bar: {second: bar}
baz: 42

So the late found values prevail:

foo: second
bar: {second: bar}
baz: 42


Aggregation is permitted between tagged objects that share the same type. If not, the default merge strategy prevails.

For example, these examples:

foo: {first: value}
foo: !aggr-map {second: value}

bar: !aggr-map {first: value}
bar: 42

baz: !aggr-seq [42]
baz: [fail]

qux: 42
qux: !aggr-scalar fail

are interpreted like this:

foo: !aggr-map{second: value}

bar: 42

baz: [fail]

qux: !aggr-seq [fail]


TODO: write this part

class salt.utils.aggregation.Aggregate

Aggregation base.

class salt.utils.aggregation.Map

Map aggregation.

class salt.utils.aggregation.OrderedDict

Dictionary that remembers insertion order

clear() None.  Remove all items from od.
copy() a shallow copy of od

Create a new ordered dictionary with keys from iterable and values set to value.

items() a set-like object providing a view on D's items
keys() a set-like object providing a view on D's keys
move_to_end(key, last=True)

Move an existing element to the end (or beginning if last is false).

Raise KeyError if the element does not exist.

pop(k[, d]) v, remove specified key and return the corresponding

value. If key is not found, d is returned if given, otherwise KeyError is raised.


Remove and return a (key, value) pair from the dictionary.

Pairs are returned in LIFO order if last is true or FIFO order if false.

setdefault(key, default=None)

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

update([E, ]**F) None.  Update D from dict/iterable E and F.

If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

values() an object providing a view on D's values

Shortcut for Sequence creation

>>> Scalar('foo') == Sequence(['foo'])
class salt.utils.aggregation.Sequence(iterable=(), /)

Sequence aggregation.

salt.utils.aggregation.aggregate(obj_a, obj_b, level=False, map_class=<class 'salt.utils.aggregation.Map'>, sequence_class=<class 'salt.utils.aggregation.Sequence'>)

Merge obj_b into obj_a.

>>> aggregate('first', 'second', True) == ['first', 'second']

Describe which levels are allowed to do deep merging.

level can be:


all levels are True


all levels are False

an int

only the first levels are True, the others are False

a sequence

it describes which levels are True, it can be:

  • a list of bool and int values

  • a string of 0 and 1 characters

salt.utils.aggregation.mark(obj, map_class=<class 'salt.utils.aggregation.Map'>, sequence_class=<class 'salt.utils.aggregation.Sequence'>)

Convert obj into an Aggregate instance