Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/rfc3986/uri.py: 67%

30 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-07 06:04 +0000

1"""Module containing the implementation of the URIReference class.""" 

2# Copyright (c) 2014 Rackspace 

3# Copyright (c) 2015 Ian Stapleton Cordasco 

4# Licensed under the Apache License, Version 2.0 (the "License"); 

5# you may not use this file except in compliance with the License. 

6# You may obtain a copy of the License at 

7# 

8# http://www.apache.org/licenses/LICENSE-2.0 

9# 

10# Unless required by applicable law or agreed to in writing, software 

11# distributed under the License is distributed on an "AS IS" BASIS, 

12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 

13# implied. 

14# See the License for the specific language governing permissions and 

15# limitations under the License. 

16from collections import namedtuple 

17 

18from . import compat 

19from . import misc 

20from . import normalizers 

21from ._mixin import URIMixin 

22 

23 

24class URIReference(namedtuple("URIReference", misc.URI_COMPONENTS), URIMixin): 

25 """Immutable object representing a parsed URI Reference. 

26 

27 .. note:: 

28 

29 This class is not intended to be directly instantiated by the user. 

30 

31 This object exposes attributes for the following components of a 

32 URI: 

33 

34 - scheme 

35 - authority 

36 - path 

37 - query 

38 - fragment 

39 

40 .. attribute:: scheme 

41 

42 The scheme that was parsed for the URI Reference. For example, 

43 ``http``, ``https``, ``smtp``, ``imap``, etc. 

44 

45 .. attribute:: authority 

46 

47 Component of the URI that contains the user information, host, 

48 and port sub-components. For example, 

49 ``google.com``, ``127.0.0.1:5000``, ``username@[::1]``, 

50 ``username:password@example.com:443``, etc. 

51 

52 .. attribute:: path 

53 

54 The path that was parsed for the given URI Reference. For example, 

55 ``/``, ``/index.php``, etc. 

56 

57 .. attribute:: query 

58 

59 The query component for a given URI Reference. For example, ``a=b``, 

60 ``a=b%20c``, ``a=b+c``, ``a=b,c=d,e=%20f``, etc. 

61 

62 .. attribute:: fragment 

63 

64 The fragment component of a URI. For example, ``section-3.1``. 

65 

66 This class also provides extra attributes for easier access to information 

67 like the subcomponents of the authority component. 

68 

69 .. attribute:: userinfo 

70 

71 The user information parsed from the authority. 

72 

73 .. attribute:: host 

74 

75 The hostname, IPv4, or IPv6 address parsed from the authority. 

76 

77 .. attribute:: port 

78 

79 The port parsed from the authority. 

80 """ 

81 

82 slots = () 

83 

84 def __new__( 

85 cls, scheme, authority, path, query, fragment, encoding="utf-8" 

86 ): 

87 """Create a new URIReference.""" 

88 ref = super().__new__( 

89 cls, 

90 scheme or None, 

91 authority or None, 

92 path or None, 

93 query, 

94 fragment, 

95 ) 

96 ref.encoding = encoding 

97 return ref 

98 

99 __hash__ = tuple.__hash__ 

100 

101 def __eq__(self, other): 

102 """Compare this reference to another.""" 

103 other_ref = other 

104 if isinstance(other, tuple): 

105 other_ref = URIReference(*other) 

106 elif not isinstance(other, URIReference): 

107 try: 

108 other_ref = URIReference.from_string(other) 

109 except TypeError: 

110 raise TypeError( 

111 "Unable to compare URIReference() to {}()".format( 

112 type(other).__name__ 

113 ) 

114 ) 

115 

116 # See http://tools.ietf.org/html/rfc3986#section-6.2 

117 naive_equality = tuple(self) == tuple(other_ref) 

118 return naive_equality or self.normalized_equality(other_ref) 

119 

120 def normalize(self): 

121 """Normalize this reference as described in Section 6.2.2. 

122 

123 This is not an in-place normalization. Instead this creates a new 

124 URIReference. 

125 

126 :returns: A new reference object with normalized components. 

127 :rtype: URIReference 

128 """ 

129 # See http://tools.ietf.org/html/rfc3986#section-6.2.2 for logic in 

130 # this method. 

131 return URIReference( 

132 normalizers.normalize_scheme(self.scheme or ""), 

133 normalizers.normalize_authority( 

134 (self.userinfo, self.host, self.port) 

135 ), 

136 normalizers.normalize_path(self.path or ""), 

137 normalizers.normalize_query(self.query), 

138 normalizers.normalize_fragment(self.fragment), 

139 self.encoding, 

140 ) 

141 

142 @classmethod 

143 def from_string(cls, uri_string, encoding="utf-8"): 

144 """Parse a URI reference from the given unicode URI string. 

145 

146 :param str uri_string: Unicode URI to be parsed into a reference. 

147 :param str encoding: The encoding of the string provided 

148 :returns: :class:`URIReference` or subclass thereof 

149 """ 

150 uri_string = compat.to_str(uri_string, encoding) 

151 

152 split_uri = misc.URI_MATCHER.match(uri_string).groupdict() 

153 return cls( 

154 split_uri["scheme"], 

155 split_uri["authority"], 

156 normalizers.encode_component(split_uri["path"], encoding), 

157 normalizers.encode_component(split_uri["query"], encoding), 

158 normalizers.encode_component(split_uri["fragment"], encoding), 

159 encoding, 

160 )