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)
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