|
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