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