Beispiel #1
0
def resolve_partial(ns, spec):
    if not isinstance(ns, ChainMap):
        ns = ChainMap(ns)
    if _namespaces not in ns:
        ns.maps[-1][_namespaces] = {}

    remainder = ()
    if not spec:
        return (), ns
    nsmap = ns[_namespaces]

    if spec in nsmap:
        return tuple(), nsmap[spec]


    for i  in range(len(spec)):

        currspec = spec[:i+1]
        if currspec in nsmap:
            ns = nsmap[currspec]
            continue
        ele = currspec[-1]
        try:
            val = extract_nsval(ns, ele)
        except ElementNotFound:
            #currspec and remainder overlap in one element
            remainder = spec[i:]
            break
        ns = ns.new_child(val)
        nsmap[currspec] = ns

    return remainder, ns
Beispiel #2
0
def resolve_partial(d, spec):
    remainder = deque(spec)

    #parts = deque([d])
    res = ChainMap(d)

    while remainder:
        ele = remainder[0]
        if isinstance(ele, tuple):
            name, index = ele
        else:
            name, index = ele, None

        if '_namespaces' in d:
            d = ChainMap(d['_namespaces'], d)

        if name in d:
            val = extract_nsval(d, name)
            if isinstance(val, dict):
                if index is not None:
                    raise TypeError("Value %s is a dict, but a "
                    "list index was specified" % name)
                res = res.new_child(val)
                remainder.popleft()
            elif isinstance(val, list):
                if index is None:
                    raise TypeError("Value %s is a list, but no "
                    "list index was specified." % name)
                val = val[index]
                if hasattr(val, 'as_namespace'):
                    if '_namespaces' in d:
                        d['_namespaces'] = {}
                    if not name in d['_namespaces']:
                        d['_namespcaces']['name'] = val.as_namespace()
                    val = d['_namespcaces']['name']
                if isinstance(val, dict):
                    res = res.new_child(val)
                    remainder.popleft()
                else:
                    raise TypeError("Value %s in list %s must "
                    "be a dictionary, not %s" % (val, ele, type(val)))
            else:
                raise TypeError("Value %s in %s is not expandable "
                                "as namespace" % (val, d))
            d = res
        else:
            break
    return(remainder, res)