示例#1
0
    def resolve_remote_with_uri(
            self, doc: Any,
            parts_idx: int) -> Tuple[Optional[URI], Optional[Any]]:
        """Defer resolution of references to a new RefPointer.

        :param doc: document element.
        :param parts_idx: index of the reference part reached.
        :return: tuple indicating (1) if doc was a ref (the ref URI returned)
            and (2) what that ref value was.
        """
        if not (isinstance(doc, abc.Mapping)
                and isinstance(doc.get("$ref"), str)):
            return None, None
        remote_uri = self.uri.relative(doc["$ref"]).get(
            *[parse_segment(part) for part in self.parts[parts_idx + 1:]])

        resolved_remote_uri, value = resolve_uri_to_urivalue_pair(remote_uri)
        return resolved_remote_uri, value
示例#2
0
def _materialize_recursive(
    conf: MaterializeConf,
    repeats: Dict[URI, _RepeatCache],
    pointer: str,
    item: Any,
) -> Any:
    """Recursive function for materializing RefDict/RefList objects.

    Keeps track of previously seen items, and stores a reference on
    repeats. Cyclical references are avoided this way, and must be
    added in afterwards (see `materialize`).

    :param conf: `MaterializeConf` object specifying any transformations
        to perform.
    :param repeats: Shared mutable dictionary for keeping track of
        items which appear multiple times (sometimes in the same path).
    :param pointer: Pointer of the current item relative to the first
        call.
    :param item: The data object to operate on.
    :return: The materialized version of `item`, or `None` if this URI
        has already been traversed elsewhere.
    """
    # End-cases
    if not isinstance(item, (RefDict, RefList)):
        return conf.value_map(item)
    if item.uri in repeats:
        repeats[item.uri][1].add(JsonPointer(pointer))
        return None
    # Keep a record of walking this URI and recurse through the
    # contained items.
    repeats[item.uri] = _RepeatCache(source=JsonPointer(pointer),
                                     repeats=set())
    recur = lambda seg, data: _materialize_recursive(
        conf, repeats,
        _next_path(pointer)(parse_segment(seg)), data)
    if isinstance(item, RefList):
        return [recur(str(idx), subitem) for idx, subitem in enumerate(item)]
    return {
        **conf.label(item),
        **{
            key: recur(key, value)
            for key, value in item.items() if conf.match_key(key)
        },
    }
示例#3
0
 def __getitem__(self, key: str):
     """Propagate ref resolution behaviour to nested objects."""
     item = super().__getitem__(key)
     uri = self.uri.get(parse_segment(key))
     return propagate(uri, item)
示例#4
0
 def recur(seg, data):
     return _materialize_recursive(
         conf, repeats, _next_path(pointer)(parse_segment(seg)), data
     )