示例#1
0
    def _dereference(self, urlstring):
        """
    Dereference the URL string.

    Returns the parsed URL, the object path extraced from the URL, and the
    dereferenced object.
    """
        # Parse URL
        parsed_url = _url.absurl(urlstring, self.parsed_url)

        # In order to start dereferencing anything in the referenced URL, we have
        # to read and parse it, of course.
        parsed_url, referenced = self._fetch_url(parsed_url)
        obj_path = parsed_url.fragment.split('/')
        while len(obj_path) and not obj_path[0]:
            obj_path = obj_path[1:]

        # In this inner parser's specification, we can now look for the referenced
        # object.
        value = referenced
        if len(obj_path) != 0:
            from dpath import util as dutil
            try:
                value = dutil.get(referenced, obj_path)
            except KeyError:
                raise _url.ResolutionError('Cannot resolve reference "%s"!' %
                                           (urlstring, ))
        return parsed_url, obj_path, value
示例#2
0
def default_reclimit_handler(limit, parsed_url, recursions=()):
    """Raise prance.util.url.ResolutionError."""
    path = []
    for rc in recursions:
        path.append('%s#/%s' % (rc[0], '/'.join(rc[1])))
    path = '\n'.join(path)

    raise _url.ResolutionError('Recursion reached limit of %d trying to '
                               'resolve "%s"!\n%s' %
                               (limit, parsed_url.geturl(), path))
示例#3
0
def default_reclimit_handler(limit, parsed_url, recursions=()):
    """Raise prance.util.url.ResolutionError."""
    path = []
    for rc in recursions:
        path.append("{}#/{}".format(rc[0], "/".join(rc[1])))
    path = "\n".join(path)

    raise _url.ResolutionError("Recursion reached limit of %d trying to "
                               'resolve "%s"!\n%s' %
                               (limit, parsed_url.geturl(), path))
示例#4
0
    def _dereference(self, ref_url, obj_path):
        """
        Dereference the URL and object path.

        Returns the dereferenced object.

        :param mixed ref_url: The URL at which the reference is located.
        :param list obj_path: The object path within the URL resource.
        :param tuple recursions: A recursion stack for resolving references.
        :return: A copy of the dereferenced value, with all internal references
            resolved.
        """
        # In order to start dereferencing anything in the referenced URL, we have
        # to read and parse it, of course.
        contents = _url.fetch_url(ref_url,
                                  self.__reference_cache,
                                  strict=self.__strict)

        # In this inner parser's specification, we can now look for the referenced
        # object.
        value = contents
        if len(obj_path) != 0:
            from prance.util.path import path_get

            try:
                value = path_get(value, obj_path)
            except (KeyError, IndexError, TypeError) as ex:
                raise _url.ResolutionError(
                    f'Cannot resolve reference "{ref_url.geturl()}": {str(ex)}'
                )

        # Deep copy value; we don't want to create recursive structures
        import copy

        value = copy.deepcopy(value)

        # Now resolve partial specs
        value = self._translate_partial(ref_url, value)

        # That's it!
        return value
示例#5
0
    def _dereferencing_iterator(self, partial, parent_path=()):
        """
    Iterate over a partial spec, dereferencing all references within.

    Yields the resolved path and value of all items that need substituting.

    :param dict partial: The partial specs to work on.
    :param tuple parent_path: The parent path of the partial specs.
    """
        from .iterators import reference_iterator
        for _, refstring, item_path in reference_iterator(partial):
            # Resolve the reference we're currently dealing with.
            _, ref_path, referenced = self._dereference(refstring)
            ref_path = tuple(ref_path)

            # If the combination of parent path and ref path already exists,
            # we're recursing and shouldn't call _dereferencing_iterator.
            recursion_key = (parent_path, ref_path)
            if recursion_key in self.__recursion_protection:
                raise _url.ResolutionError(
                    'Recursion detected trying to resolve "%s"!' %
                    (refstring, ))
            self.__recursion_protection.add(recursion_key)

            # If the referenced object contains any reference, yield all the items
            # in it that need dereferencing.
            for inner in self._dereferencing_iterator(referenced, ref_path):
                yield inner

            # We can remove ourselves from the recursion protection again after
            # children are processed.
            self.__recursion_protection.remove(recursion_key)

            # Afterwards also yield the outer item. This makes the
            # _dereferencing_iterator work depth first.
            yield parent_path + item_path, referenced
示例#6
0
def default_reclimit_handler(limit, parsed_url):
    """Raise prance.util.url.ResolutionError."""
    raise _url.ResolutionError('Recursion reached limit of %d trying to '
                               'resolve "%s"!' % (limit, parsed_url.geturl()))