import collections
import itertools


# from jaraco.collections 3.5
class DictStack(list, collections.abc.Mapping):
    """
    A stack of dictionaries that behaves as a view on those dictionaries,
    giving preference to the last.

    >>> stack = DictStack([dict(a=1, c=2), dict(b=2, a=2)])
    >>> stack['a']
    2
    >>> stack['b']
    2
    >>> stack['c']
    2
    >>> stack.push(dict(a=3))
    >>> stack['a']
    3
    >>> set(stack.keys()) == set(['a', 'b', 'c'])
    True
    >>> set(stack.items()) == set([('a', 3), ('b', 2), ('c', 2)])
    True
    >>> dict(**stack) == dict(stack) == dict(a=3, c=2, b=2)
    True
    >>> d = stack.pop()
    >>> stack['a']
    2
    >>> d = stack.pop()
    >>> stack['a']
    1
    >>> stack.get('b', None)
    >>> 'c' in stack
    True
    """

    def __iter__(self):
        dicts = list.__iter__(self)
        return iter(set(itertools.chain.from_iterable(c.keys() for c in dicts)))

    def __getitem__(self, key):
        for scope in reversed(self):
            if key in scope:
                return scope[key]
        raise KeyError(key)

    push = list.append

    def __contains__(self, other):
        return collections.abc.Mapping.__contains__(self, other)

import collections
import itertools


# from jaraco.collections 3.5.1
class DictStack(list, collections.abc.Mapping):
    """
    A stack of dictionaries that behaves as a view on those dictionaries,
    giving preference to the last.

    >>> stack = DictStack([dict(a=1, c=2), dict(b=2, a=2)])
    >>> stack['a']
    2
    >>> stack['b']
    2
    >>> stack['c']
    2
    >>> len(stack)
    3
    >>> stack.push(dict(a=3))
    >>> stack['a']
    3
    >>> set(stack.keys()) == set(['a', 'b', 'c'])
    True
    >>> set(stack.items()) == set([('a', 3), ('b', 2), ('c', 2)])
    True
    >>> dict(**stack) == dict(stack) == dict(a=3, c=2, b=2)
    True
    >>> d = stack.pop()
    >>> stack['a']
    2
    >>> d = stack.pop()
    >>> stack['a']
    1
    >>> stack.get('b', None)
    >>> 'c' in stack
    True
    """

    def __iter__(self):
        dicts = list.__iter__(self)
        return iter(set(itertools.chain.from_iterable(c.keys() for c in dicts)))

    def __getitem__(self, key):
        for scope in reversed(tuple(list.__iter__(self))):
            if key in scope:
                return scope[key]
        raise KeyError(key)

    push = list.append

    def __contains__(self, other):
        return collections.abc.Mapping.__contains__(self, other)

    def __len__(self):
        return len(list(iter(self)))

Update DictStack implementation from jaraco.collections 3.5.1
Update DictStack implementation from jaraco.collections 3.5.1

  import collections
  import itertools
  
  
- # from jaraco.collections 3.5
+ # from jaraco.collections 3.5.1
  class DictStack(list, collections.abc.Mapping):
      """
      A stack of dictionaries that behaves as a view on those dictionaries,
      giving preference to the last.
  
      >>> stack = DictStack([dict(a=1, c=2), dict(b=2, a=2)])
      >>> stack['a']
      2
      >>> stack['b']
      2
      >>> stack['c']
      2
+     >>> len(stack)
+     3
      >>> stack.push(dict(a=3))
      >>> stack['a']
      3
      >>> set(stack.keys()) == set(['a', 'b', 'c'])
      True
      >>> set(stack.items()) == set([('a', 3), ('b', 2), ('c', 2)])
      True
      >>> dict(**stack) == dict(stack) == dict(a=3, c=2, b=2)
      True
      >>> d = stack.pop()
      >>> stack['a']
      2
      >>> d = stack.pop()
      >>> stack['a']
      1
      >>> stack.get('b', None)
      >>> 'c' in stack
      True
      """
  
      def __iter__(self):
          dicts = list.__iter__(self)
          return iter(set(itertools.chain.from_iterable(c.keys() for c in dicts)))
  
      def __getitem__(self, key):
-         for scope in reversed(self):
+         for scope in reversed(tuple(list.__iter__(self))):
              if key in scope:
                  return scope[key]
          raise KeyError(key)
  
      push = list.append
  
      def __contains__(self, other):
          return collections.abc.Mapping.__contains__(self, other)
  
+     def __len__(self):
+         return len(list(iter(self)))
+ 
Update DictStack implementation from jaraco.collections 3.5.1
## Code Before:
import collections
import itertools


# from jaraco.collections 3.5
class DictStack(list, collections.abc.Mapping):
    """
    A stack of dictionaries that behaves as a view on those dictionaries,
    giving preference to the last.

    >>> stack = DictStack([dict(a=1, c=2), dict(b=2, a=2)])
    >>> stack['a']
    2
    >>> stack['b']
    2
    >>> stack['c']
    2
    >>> stack.push(dict(a=3))
    >>> stack['a']
    3
    >>> set(stack.keys()) == set(['a', 'b', 'c'])
    True
    >>> set(stack.items()) == set([('a', 3), ('b', 2), ('c', 2)])
    True
    >>> dict(**stack) == dict(stack) == dict(a=3, c=2, b=2)
    True
    >>> d = stack.pop()
    >>> stack['a']
    2
    >>> d = stack.pop()
    >>> stack['a']
    1
    >>> stack.get('b', None)
    >>> 'c' in stack
    True
    """

    def __iter__(self):
        dicts = list.__iter__(self)
        return iter(set(itertools.chain.from_iterable(c.keys() for c in dicts)))

    def __getitem__(self, key):
        for scope in reversed(self):
            if key in scope:
                return scope[key]
        raise KeyError(key)

    push = list.append

    def __contains__(self, other):
        return collections.abc.Mapping.__contains__(self, other)

## Instruction:
Update DictStack implementation from jaraco.collections 3.5.1
## Code After:
import collections
import itertools


# from jaraco.collections 3.5.1
class DictStack(list, collections.abc.Mapping):
    """
    A stack of dictionaries that behaves as a view on those dictionaries,
    giving preference to the last.

    >>> stack = DictStack([dict(a=1, c=2), dict(b=2, a=2)])
    >>> stack['a']
    2
    >>> stack['b']
    2
    >>> stack['c']
    2
    >>> len(stack)
    3
    >>> stack.push(dict(a=3))
    >>> stack['a']
    3
    >>> set(stack.keys()) == set(['a', 'b', 'c'])
    True
    >>> set(stack.items()) == set([('a', 3), ('b', 2), ('c', 2)])
    True
    >>> dict(**stack) == dict(stack) == dict(a=3, c=2, b=2)
    True
    >>> d = stack.pop()
    >>> stack['a']
    2
    >>> d = stack.pop()
    >>> stack['a']
    1
    >>> stack.get('b', None)
    >>> 'c' in stack
    True
    """

    def __iter__(self):
        dicts = list.__iter__(self)
        return iter(set(itertools.chain.from_iterable(c.keys() for c in dicts)))

    def __getitem__(self, key):
        for scope in reversed(tuple(list.__iter__(self))):
            if key in scope:
                return scope[key]
        raise KeyError(key)

    push = list.append

    def __contains__(self, other):
        return collections.abc.Mapping.__contains__(self, other)

    def __len__(self):
        return len(list(iter(self)))
