mercurial/thirdparty/jaraco/collections.py
changeset 50643 cbcbf63b6dbf
parent 50641 5460424092e2
child 50644 89556caf3c66
equal deleted inserted replaced
50641:5460424092e2 50643:cbcbf63b6dbf
     1 # adapted from jaraco.collections 3.9
       
     2 
       
     3 import collections
       
     4 
       
     5 
       
     6 class Projection(collections.abc.Mapping):
       
     7     """
       
     8     Project a set of keys over a mapping
       
     9 
       
    10     >>> sample = {'a': 1, 'b': 2, 'c': 3}
       
    11     >>> prj = Projection(['a', 'c', 'd'], sample)
       
    12     >>> prj == {'a': 1, 'c': 3}
       
    13     True
       
    14 
       
    15     Keys should only appear if they were specified and exist in the space.
       
    16 
       
    17     >>> sorted(list(prj.keys()))
       
    18     ['a', 'c']
       
    19 
       
    20     Attempting to access a key not in the projection
       
    21     results in a KeyError.
       
    22 
       
    23     >>> prj['b']
       
    24     Traceback (most recent call last):
       
    25     ...
       
    26     KeyError: 'b'
       
    27 
       
    28     Use the projection to update another dict.
       
    29 
       
    30     >>> target = {'a': 2, 'b': 2}
       
    31     >>> target.update(prj)
       
    32     >>> target == {'a': 1, 'b': 2, 'c': 3}
       
    33     True
       
    34 
       
    35     Also note that Projection keeps a reference to the original dict, so
       
    36     if you modify the original dict, that could modify the Projection.
       
    37 
       
    38     >>> del sample['a']
       
    39     >>> dict(prj)
       
    40     {'c': 3}
       
    41     """
       
    42 
       
    43     def __init__(self, keys, space):
       
    44         self._keys = tuple(keys)
       
    45         self._space = space
       
    46 
       
    47     def __getitem__(self, key):
       
    48         if key not in self._keys:
       
    49             raise KeyError(key)
       
    50         return self._space[key]
       
    51 
       
    52     def __iter__(self):
       
    53         return iter(set(self._keys).intersection(self._space))
       
    54 
       
    55     def __len__(self):
       
    56         return len(tuple(iter(self)))