|
1 |
| -from collections import ChainMap |
| 1 | +from typing import ChainMap, MutableMapping, TypeVar, cast |
2 | 2 |
|
| 3 | +_KT = TypeVar("_KT") |
| 4 | +_VT = TypeVar("_VT") |
3 | 5 |
|
4 |
| -class DeepChainMap(ChainMap): |
5 |
| - def __setitem__(self, key, value): |
| 6 | + |
| 7 | +class DeepChainMap(ChainMap[_KT, _VT]): |
| 8 | + """Variant of ChainMap that allows direct updates to inner scopes. |
| 9 | +
|
| 10 | + Only works when all passed mapping are mutable. |
| 11 | + """ |
| 12 | + |
| 13 | + def __setitem__(self, key: _KT, value: _VT) -> None: |
6 | 14 | for mapping in self.maps:
|
7 |
| - if key in mapping: |
8 |
| - mapping[key] = value |
| 15 | + mutable_mapping = cast(MutableMapping[_KT, _VT], mapping) |
| 16 | + if key in mutable_mapping: |
| 17 | + mutable_mapping[key] = value |
9 | 18 | return
|
10 |
| - self.maps[0][key] = value |
| 19 | + cast(MutableMapping[_KT, _VT], self.maps[0])[key] = value |
11 | 20 |
|
12 |
| - def __delitem__(self, key): |
| 21 | + def __delitem__(self, key: _KT) -> None: |
13 | 22 | """
|
14 | 23 | Raises
|
15 | 24 | ------
|
16 | 25 | KeyError
|
17 | 26 | If `key` doesn't exist.
|
18 | 27 | """
|
19 | 28 | for mapping in self.maps:
|
| 29 | + mutable_mapping = cast(MutableMapping[_KT, _VT], mapping) |
20 | 30 | if key in mapping:
|
21 |
| - del mapping[key] |
| 31 | + del mutable_mapping[key] |
22 | 32 | return
|
23 | 33 | raise KeyError(key)
|
0 commit comments