Begin work on reference resolution

This commit is contained in:
Ian Cordasco
2014-07-04 09:43:35 -05:00
parent 6aab2b2917
commit 958c9cf738
2 changed files with 44 additions and 3 deletions

View File

@@ -7,3 +7,9 @@ class InvalidAuthority(RFC3986Exception):
def __init__(self, authority):
super(InvalidAuthority, self).__init__(
"The authority ({0}) is not valid.".format(authority))
class ResolutionError(RFC3986Exception):
def __init__(self, uri):
super(ResolutionError, self).__init__(
"{0} is not an absolute URI.".format(uri.unsplit()))

View File

@@ -15,10 +15,11 @@
from collections import namedtuple
from .compat import to_str
from .exceptions import InvalidAuthority
from .exceptions import InvalidAuthority, ResolutionError
from .misc import (
FRAGMENT_MATCHER, IPv4_MATCHER, PATH_MATCHER, QUERY_MATCHER,
SCHEME_MATCHER, SUBAUTHORITY_MATCHER, URI_MATCHER, URI_COMPONENTS
ABSOLUTE_URI_MATCHER, FRAGMENT_MATCHER, IPv4_MATCHER, PATH_MATCHER,
QUERY_MATCHER, SCHEME_MATCHER, SUBAUTHORITY_MATCHER, URI_MATCHER,
URI_COMPONENTS
)
from .normalizers import (
encode_component, normalize_scheme, normalize_authority, normalize_path,
@@ -139,6 +140,18 @@ class URIReference(namedtuple('URIReference', URI_COMPONENTS)):
return None
return authority['userinfo']
def is_absolute(self):
"""Determine if this URI Reference is an absolute URI.
See http://tools.ietf.org/html/rfc3986#section-4.3 for explanation.
:returns: ``True`` if it is an absolute URI, ``False`` otherwise.
:rtype: bool
"""
if ABSOLUTE_URI_MATCHER.match(self.unsplit()):
return True
return False
def is_valid(self, **kwargs):
"""Determines if the URI is valid.
@@ -266,6 +279,28 @@ class URIReference(namedtuple('URIReference', URI_COMPONENTS)):
"""
return tuple(self.normalize()) == tuple(other_ref.normalize())
def resolve(self, base_uri, strict=False):
"""Use an absolute URI Reference to resolve this relative reference.
See http://tools.ietf.org/html/rfc3986#section-5 for more information.
:param base_uri: Either a string or URIReference. It must be an
absolute URI or it will raise an exception.
:returns: A new URIReference which is the result of resolving this
reference using ``base_uri``.
:rtype: :class:`URIReference`
:raises ResolutionError: If the ``base_uri`` is not an absolute URI.
"""
if not isinstance(base_uri, URIReference):
base_uri = URIReference.from_string(base_uri)
if not base_uri.is_absolute():
raise ResolutionError(base_uri)
# This is optional per
# http://tools.ietf.org/html/rfc3986#section-5.2.1
base_uri = base_uri.normalize()
def unsplit(self):
"""Create a URI string from the components.