Spaces:
Runtime error
Runtime error
"""Module containing the implementation of the URIReference class.""" | |
# -*- coding: utf-8 -*- | |
# Copyright (c) 2014 Rackspace | |
# Copyright (c) 2015 Ian Stapleton Cordasco | |
# Licensed under the Apache License, Version 2.0 (the "License"); | |
# you may not use this file except in compliance with the License. | |
# You may obtain a copy of the License at | |
# | |
# http://www.apache.org/licenses/LICENSE-2.0 | |
# | |
# Unless required by applicable law or agreed to in writing, software | |
# distributed under the License is distributed on an "AS IS" BASIS, | |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |
# implied. | |
# See the License for the specific language governing permissions and | |
# limitations under the License. | |
from collections import namedtuple | |
from . import compat | |
from . import misc | |
from . import normalizers | |
from ._mixin import URIMixin | |
class URIReference(namedtuple("URIReference", misc.URI_COMPONENTS), URIMixin): | |
"""Immutable object representing a parsed URI Reference. | |
.. note:: | |
This class is not intended to be directly instantiated by the user. | |
This object exposes attributes for the following components of a | |
URI: | |
- scheme | |
- authority | |
- path | |
- query | |
- fragment | |
.. attribute:: scheme | |
The scheme that was parsed for the URI Reference. For example, | |
``http``, ``https``, ``smtp``, ``imap``, etc. | |
.. attribute:: authority | |
Component of the URI that contains the user information, host, | |
and port sub-components. For example, | |
``google.com``, ``127.0.0.1:5000``, ``username@[::1]``, | |
``username:password@example.com:443``, etc. | |
.. attribute:: path | |
The path that was parsed for the given URI Reference. For example, | |
``/``, ``/index.php``, etc. | |
.. attribute:: query | |
The query component for a given URI Reference. For example, ``a=b``, | |
``a=b%20c``, ``a=b+c``, ``a=b,c=d,e=%20f``, etc. | |
.. attribute:: fragment | |
The fragment component of a URI. For example, ``section-3.1``. | |
This class also provides extra attributes for easier access to information | |
like the subcomponents of the authority component. | |
.. attribute:: userinfo | |
The user information parsed from the authority. | |
.. attribute:: host | |
The hostname, IPv4, or IPv6 address parsed from the authority. | |
.. attribute:: port | |
The port parsed from the authority. | |
""" | |
slots = () | |
def __new__( | |
cls, scheme, authority, path, query, fragment, encoding="utf-8" | |
): | |
"""Create a new URIReference.""" | |
ref = super(URIReference, cls).__new__( | |
cls, | |
scheme or None, | |
authority or None, | |
path or None, | |
query, | |
fragment, | |
) | |
ref.encoding = encoding | |
return ref | |
__hash__ = tuple.__hash__ | |
def __eq__(self, other): | |
"""Compare this reference to another.""" | |
other_ref = other | |
if isinstance(other, tuple): | |
other_ref = URIReference(*other) | |
elif not isinstance(other, URIReference): | |
try: | |
other_ref = URIReference.from_string(other) | |
except TypeError: | |
raise TypeError( | |
"Unable to compare URIReference() to {0}()".format( | |
type(other).__name__ | |
) | |
) | |
# See http://tools.ietf.org/html/rfc3986#section-6.2 | |
naive_equality = tuple(self) == tuple(other_ref) | |
return naive_equality or self.normalized_equality(other_ref) | |
def normalize(self): | |
"""Normalize this reference as described in Section 6.2.2. | |
This is not an in-place normalization. Instead this creates a new | |
URIReference. | |
:returns: A new reference object with normalized components. | |
:rtype: URIReference | |
""" | |
# See http://tools.ietf.org/html/rfc3986#section-6.2.2 for logic in | |
# this method. | |
return URIReference( | |
normalizers.normalize_scheme(self.scheme or ""), | |
normalizers.normalize_authority( | |
(self.userinfo, self.host, self.port) | |
), | |
normalizers.normalize_path(self.path or ""), | |
normalizers.normalize_query(self.query), | |
normalizers.normalize_fragment(self.fragment), | |
self.encoding, | |
) | |
def from_string(cls, uri_string, encoding="utf-8"): | |
"""Parse a URI reference from the given unicode URI string. | |
:param str uri_string: Unicode URI to be parsed into a reference. | |
:param str encoding: The encoding of the string provided | |
:returns: :class:`URIReference` or subclass thereof | |
""" | |
uri_string = compat.to_str(uri_string, encoding) | |
split_uri = misc.URI_MATCHER.match(uri_string).groupdict() | |
return cls( | |
split_uri["scheme"], | |
split_uri["authority"], | |
normalizers.encode_component(split_uri["path"], encoding), | |
normalizers.encode_component(split_uri["query"], encoding), | |
normalizers.encode_component(split_uri["fragment"], encoding), | |
encoding, | |
) | |