diff --git a/killswitch.py b/killswitch.py index fd93cedb..499b71e2 100644 --- a/killswitch.py +++ b/killswitch.py @@ -113,7 +113,25 @@ def _deep_apply(target: UPDATABLE_DATA, path: str, to_set=None, delete=False): # it exists on this level, dont go further break - key, _, path = path.partition('.') + elif isinstance(current, Mapping) and any('.' in k and path.startswith(k) for k in current.keys()): + # there is a dotted key in here that can be used for this + # if theres a dotted key in here (must be a mapping), use that if we can + + keys = current.keys() + for k in filter(lambda x: '.' in x, keys): + if path.startswith(k): + key = k + path = path.removeprefix(k) + # we assume that the `.` here is for "accessing" the next key. + if path[0] == '.': + path = path[1:] + + if len(path) == 0: + path = key + break + + else: + key, _, path = path.partition('.') if isinstance(current, Mapping): current = current[key] # type: ignore # I really dont know at this point what you want from me mypy. diff --git a/tests/killswitch.py/test_apply.py b/tests/killswitch.py/test_apply.py index 5033163e..2bbb20c5 100644 --- a/tests/killswitch.py/test_apply.py +++ b/tests/killswitch.py/test_apply.py @@ -72,7 +72,10 @@ def test_get_int(input: str, expected: Optional[int]) -> None: ({'depth': {'is': 'important'}}, 'depth.is', '', 'nonexistent', {'depth': {'is': 'nonexistent'}}), ([{'test': ['stuff']}], '0.test.0', '', 'things', [{'test': ['things']}]), (({'test': {'with': ['a', 'tuple']}},), '0.test.with.0', 'delete', '', ({'test': {'with': ['tuple']}},)), - ({'test': ['with a', {'set', 'of', 'stuff'}]}, 'test.1', 'delete', '', {'test': ['with a']}) + ({'test': ['with a', {'set', 'of', 'stuff'}]}, 'test.1', 'delete', '', {'test': ['with a']}), + ({'keys.can.have.': 'dots!'}, 'keys.can.have.', '', '.s!', {'keys.can.have.': '.s!'}), + ({'multilevel.keys': {'with.dots': False}}, 'multilevel.keys.with.dots', + '', True, {'multilevel.keys': {'with.dots': True}}) ], ) def test_deep_get(source: UPDATABLE_DATA, key: str, action: str, to_set: Any, result: UPDATABLE_DATA) -> None: