Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enabling (optional) KeyPath ability to write when path doesn't already exist #16

Open
thorwhalen opened this issue Dec 6, 2022 · 0 comments

Comments

@thorwhalen
Copy link
Member

thorwhalen commented Dec 6, 2022

Random Notes

Possibly related:

Old dict path get stuff

glom

remap

What we (might) want

Something like collections.defaultdict but where the factory needs to be contextual (because different levels may have different stores.

What happens if I do:

s[1][2][3][4] = val

and s[1] doesn't have the 2 key?

Maybe this:

s[1][2] = EmptyStoreType2()
s[1][2][3] = EmptyStoreType3()
s[1][2][3][4] = val 

and now non of the stores above are empty anymore.

Some code to think of

# NOTE: perhaps use glom and/or remap?

from typing import Mapping
from i2 import mk_sentinel

def is_a_mapping(store, prev_path):
    return isinstance(store, Mapping)


def mk_a_dict(prev_path):  # should we include current_key too?
    return dict()
    
    
def _split_path(
    store, path: tuple, store_to_explore_further=is_a_mapping, prev_path=()
):
    """Separate part of the path that has a value in store and the part that doesn't"""
    if not path:  # path is empty
        return prev_path, (), ()
    # else:
    key, *next_path = path
    val = store.get(key, NoSuchKey)
    if val is NoSuchKey:
        # if key doesn't exist, everything from there on is the store-invalid part
        return prev_path, (key,) + next_path
    else:
        # if key doesn't exist, everything from there on is the store-invalid part
        if store_to_explore_further(val, prev_path):
            return _advance_to_first_non_existing_key(
                val, 
                next_path, 
                store_to_explore_further, 
                prev_path=prev_path + (key,)
            ):
        else:
            return prev_path, key, next_path
            
        
NoSuchKey = mk_sentinel('NoSuchKey')

def default_store(
    store, 
    path: tuple, 
    store_to_explore_further=is_a_mapping, 
    mk_new_store=mk_a_dict  # factory part
):
#     k = k.split(store.path_sep) (if k is string)
    prev_path, problem_path = _advance_to_first_non_existing_key(
        store, path, store_to_explore_further, mk_new_store
    )
    current_path = prev_path
    current_store = store[current_path]
    for key in problem_path:
        current_path = current_path + (key,)
        current_store[key] = mk_new_store(current_path)
        current_store = current_store[key]
        
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant