Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/rfc3986/uri.py: 43%
30 statements
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 06:12 +0000
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 06:12 +0000
1"""Module containing the implementation of the URIReference class."""
2# -*- coding: utf-8 -*-
3# Copyright (c) 2014 Rackspace
4# Copyright (c) 2015 Ian Stapleton Cordasco
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14# implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17from collections import namedtuple
19from . import compat
20from . import misc
21from . import normalizers
22from ._mixin import URIMixin
25class URIReference(namedtuple("URIReference", misc.URI_COMPONENTS), URIMixin):
26 """Immutable object representing a parsed URI Reference.
28 .. note::
30 This class is not intended to be directly instantiated by the user.
32 This object exposes attributes for the following components of a
33 URI:
35 - scheme
36 - authority
37 - path
38 - query
39 - fragment
41 .. attribute:: scheme
43 The scheme that was parsed for the URI Reference. For example,
44 ``http``, ``https``, ``smtp``, ``imap``, etc.
46 .. attribute:: authority
48 Component of the URI that contains the user information, host,
49 and port sub-components. For example,
50 ``google.com``, ``127.0.0.1:5000``, ``username@[::1]``,
51 ``username:password@example.com:443``, etc.
53 .. attribute:: path
55 The path that was parsed for the given URI Reference. For example,
56 ``/``, ``/index.php``, etc.
58 .. attribute:: query
60 The query component for a given URI Reference. For example, ``a=b``,
61 ``a=b%20c``, ``a=b+c``, ``a=b,c=d,e=%20f``, etc.
63 .. attribute:: fragment
65 The fragment component of a URI. For example, ``section-3.1``.
67 This class also provides extra attributes for easier access to information
68 like the subcomponents of the authority component.
70 .. attribute:: userinfo
72 The user information parsed from the authority.
74 .. attribute:: host
76 The hostname, IPv4, or IPv6 address parsed from the authority.
78 .. attribute:: port
80 The port parsed from the authority.
81 """
83 slots = ()
85 def __new__(
86 cls, scheme, authority, path, query, fragment, encoding="utf-8"
87 ):
88 """Create a new URIReference."""
89 ref = super(URIReference, cls).__new__(
90 cls,
91 scheme or None,
92 authority or None,
93 path or None,
94 query,
95 fragment,
96 )
97 ref.encoding = encoding
98 return ref
100 __hash__ = tuple.__hash__
102 def __eq__(self, other):
103 """Compare this reference to another."""
104 other_ref = other
105 if isinstance(other, tuple):
106 other_ref = URIReference(*other)
107 elif not isinstance(other, URIReference):
108 try:
109 other_ref = URIReference.from_string(other)
110 except TypeError:
111 raise TypeError(
112 "Unable to compare URIReference() to {0}()".format(
113 type(other).__name__
114 )
115 )
117 # See http://tools.ietf.org/html/rfc3986#section-6.2
118 naive_equality = tuple(self) == tuple(other_ref)
119 return naive_equality or self.normalized_equality(other_ref)
121 def normalize(self):
122 """Normalize this reference as described in Section 6.2.2.
124 This is not an in-place normalization. Instead this creates a new
125 URIReference.
127 :returns: A new reference object with normalized components.
128 :rtype: URIReference
129 """
130 # See http://tools.ietf.org/html/rfc3986#section-6.2.2 for logic in
131 # this method.
132 return URIReference(
133 normalizers.normalize_scheme(self.scheme or ""),
134 normalizers.normalize_authority(
135 (self.userinfo, self.host, self.port)
136 ),
137 normalizers.normalize_path(self.path or ""),
138 normalizers.normalize_query(self.query),
139 normalizers.normalize_fragment(self.fragment),
140 self.encoding,
141 )
143 @classmethod
144 def from_string(cls, uri_string, encoding="utf-8"):
145 """Parse a URI reference from the given unicode URI string.
147 :param str uri_string: Unicode URI to be parsed into a reference.
148 :param str encoding: The encoding of the string provided
149 :returns: :class:`URIReference` or subclass thereof
150 """
151 uri_string = compat.to_str(uri_string, encoding)
153 split_uri = misc.URI_MATCHER.match(uri_string).groupdict()
154 return cls(
155 split_uri["scheme"],
156 split_uri["authority"],
157 normalizers.encode_component(split_uri["path"], encoding),
158 normalizers.encode_component(split_uri["query"], encoding),
159 normalizers.encode_component(split_uri["fragment"], encoding),
160 encoding,
161 )