Source code for prance.util.iterators

"""This submodule contains specialty iterators over specs."""

__author__ = "Jens Finkhaeuser"
__copyright__ = "Copyright (c) 2016-2018 Jens Finkhaeuser"
__license__ = "MIT"
__all__ = ()


[docs]def item_iterator(value, path=()): """ Return item iterator over the a nested dict- or list-like object. Returns each item value as the second item to unpack, and a tuple path to the item as the first value - in that, it behaves much like viewitems(). For list like values, the path is made up of numeric indices. Given a spec such as this:: spec = { 'foo': 42, 'bar': { 'some': 'dict', }, 'baz': [ { 1: 2 }, { 3: 4 }, ] } Here, (parts of) the yielded values would be: ======== ============= item path ======== ============= [...] ('baz',) { 1: 2 } ('baz', 0) 2 ('baz', 0, 1) ======== ============= :param dict/list value: The specifications to iterate over. :return: An iterator over all items in the value. :rtype: iterator """ # Yield the top-level object, always yield path, value from collections.abc import Mapping, Sequence # For dict and list like objects, we also need to yield each item # recursively. if isinstance(value, Mapping): for key, item in value.items(): yield from item_iterator(item, path + (key,)) elif isinstance(value, Sequence) and not isinstance(value, str): for idx, item in enumerate(value): yield from item_iterator(item, path + (idx,))
[docs]def reference_iterator(specs, path=()): """ Iterate through the given specs, returning only references. The iterator returns three values: - The key, mimicking the behaviour of other iterators, although it will always equal '$ref' - The value - The path to the item. This is a tuple of all the item's ancestors, in sequence, so that you can reasonably easily find the containing item. It does not include the final '$ref' key. :param dict specs: The specifications to iterate over. :return: An iterator over all references in the specs. :rtype: iterator """ # We need to iterate through the nested specification dict, so let's # start with an appropriate iterator. We can immediately optimize it by # only returning '$ref' items. for item_path, item in item_iterator(specs, path): if len(item_path) <= 0: continue key = item_path[-1] if key == "$ref": yield key, item, item_path[:-1]