diff options
author | Shubham Saini <shubham6405@gmail.com> | 2018-12-11 10:01:23 +0000 |
---|---|---|
committer | Shubham Saini <shubham6405@gmail.com> | 2018-12-11 10:01:23 +0000 |
commit | 68df54d6629ec019142eb149dd037774f2d11e7c (patch) | |
tree | 345bc22d46b4e01a4ba8303b94278952a4ed2b9e /venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/url.py |
First commit
Diffstat (limited to 'venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/url.py')
-rw-r--r-- | venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/url.py | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/url.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/url.py new file mode 100644 index 0000000..60f826a --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/url.py | |||
@@ -0,0 +1,230 @@ | |||
1 | from __future__ import absolute_import | ||
2 | from collections import namedtuple | ||
3 | |||
4 | from ..exceptions import LocationParseError | ||
5 | |||
6 | |||
7 | url_attrs = ['scheme', 'auth', 'host', 'port', 'path', 'query', 'fragment'] | ||
8 | |||
9 | # We only want to normalize urls with an HTTP(S) scheme. | ||
10 | # urllib3 infers URLs without a scheme (None) to be http. | ||
11 | NORMALIZABLE_SCHEMES = ('http', 'https', None) | ||
12 | |||
13 | |||
14 | class Url(namedtuple('Url', url_attrs)): | ||
15 | """ | ||
16 | Datastructure for representing an HTTP URL. Used as a return value for | ||
17 | :func:`parse_url`. Both the scheme and host are normalized as they are | ||
18 | both case-insensitive according to RFC 3986. | ||
19 | """ | ||
20 | __slots__ = () | ||
21 | |||
22 | def __new__(cls, scheme=None, auth=None, host=None, port=None, path=None, | ||
23 | query=None, fragment=None): | ||
24 | if path and not path.startswith('/'): | ||
25 | path = '/' + path | ||
26 | if scheme: | ||
27 | scheme = scheme.lower() | ||
28 | if host and scheme in NORMALIZABLE_SCHEMES: | ||
29 | host = host.lower() | ||
30 | return super(Url, cls).__new__(cls, scheme, auth, host, port, path, | ||
31 | query, fragment) | ||
32 | |||
33 | @property | ||
34 | def hostname(self): | ||
35 | """For backwards-compatibility with urlparse. We're nice like that.""" | ||
36 | return self.host | ||
37 | |||
38 | @property | ||
39 | def request_uri(self): | ||
40 | """Absolute path including the query string.""" | ||
41 | uri = self.path or '/' | ||
42 | |||
43 | if self.query is not None: | ||
44 | uri += '?' + self.query | ||
45 | |||
46 | return uri | ||
47 | |||
48 | @property | ||
49 | def netloc(self): | ||
50 | """Network location including host and port""" | ||
51 | if self.port: | ||
52 | return '%s:%d' % (self.host, self.port) | ||
53 | return self.host | ||
54 | |||
55 | @property | ||
56 | def url(self): | ||
57 | """ | ||
58 | Convert self into a url | ||
59 | |||
60 | This function should more or less round-trip with :func:`.parse_url`. The | ||
61 | returned url may not be exactly the same as the url inputted to | ||
62 | :func:`.parse_url`, but it should be equivalent by the RFC (e.g., urls | ||
63 | with a blank port will have : removed). | ||
64 | |||
65 | Example: :: | ||
66 | |||
67 | >>> U = parse_url('http://google.com/mail/') | ||
68 | >>> U.url | ||
69 | 'http://google.com/mail/' | ||
70 | >>> Url('http', 'username:password', 'host.com', 80, | ||
71 | ... '/path', 'query', 'fragment').url | ||
72 | 'http://username:password@host.com:80/path?query#fragment' | ||
73 | """ | ||
74 | scheme, auth, host, port, path, query, fragment = self | ||
75 | url = '' | ||
76 | |||
77 | # We use "is not None" we want things to happen with empty strings (or 0 port) | ||
78 | if scheme is not None: | ||
79 | url += scheme + '://' | ||
80 | if auth is not None: | ||
81 | url += auth + '@' | ||
82 | if host is not None: | ||
83 | url += host | ||
84 | if port is not None: | ||
85 | url += ':' + str(port) | ||
86 | if path is not None: | ||
87 | url += path | ||
88 | if query is not None: | ||
89 | url += '?' + query | ||
90 | if fragment is not None: | ||
91 | url += '#' + fragment | ||
92 | |||
93 | return url | ||
94 | |||
95 | def __str__(self): | ||
96 | return self.url | ||
97 | |||
98 | |||
99 | def split_first(s, delims): | ||
100 | """ | ||
101 | Given a string and an iterable of delimiters, split on the first found | ||
102 | delimiter. Return two split parts and the matched delimiter. | ||
103 | |||
104 | If not found, then the first part is the full input string. | ||
105 | |||
106 | Example:: | ||
107 | |||
108 | >>> split_first('foo/bar?baz', '?/=') | ||
109 | ('foo', 'bar?baz', '/') | ||
110 | >>> split_first('foo/bar?baz', '123') | ||
111 | ('foo/bar?baz', '', None) | ||
112 | |||
113 | Scales linearly with number of delims. Not ideal for large number of delims. | ||
114 | """ | ||
115 | min_idx = None | ||
116 | min_delim = None | ||
117 | for d in delims: | ||
118 | idx = s.find(d) | ||
119 | if idx < 0: | ||
120 | continue | ||
121 | |||
122 | if min_idx is None or idx < min_idx: | ||
123 | min_idx = idx | ||
124 | min_delim = d | ||
125 | |||
126 | if min_idx is None or min_idx < 0: | ||
127 | return s, '', None | ||
128 | |||
129 | return s[:min_idx], s[min_idx + 1:], min_delim | ||
130 | |||
131 | |||
132 | def parse_url(url): | ||
133 | """ | ||
134 | Given a url, return a parsed :class:`.Url` namedtuple. Best-effort is | ||
135 | performed to parse incomplete urls. Fields not provided will be None. | ||
136 | |||
137 | Partly backwards-compatible with :mod:`urlparse`. | ||
138 | |||
139 | Example:: | ||
140 | |||
141 | >>> parse_url('http://google.com/mail/') | ||
142 | Url(scheme='http', host='google.com', port=None, path='/mail/', ...) | ||
143 | >>> parse_url('google.com:80') | ||
144 | Url(scheme=None, host='google.com', port=80, path=None, ...) | ||
145 | >>> parse_url('/foo?bar') | ||
146 | Url(scheme=None, host=None, port=None, path='/foo', query='bar', ...) | ||
147 | """ | ||
148 | |||
149 | # While this code has overlap with stdlib's urlparse, it is much | ||
150 | # simplified for our needs and less annoying. | ||
151 | # Additionally, this implementations does silly things to be optimal | ||
152 | # on CPython. | ||
153 | |||
154 | if not url: | ||
155 | # Empty | ||
156 | return Url() | ||
157 | |||
158 | scheme = None | ||
159 | auth = None | ||
160 | host = None | ||
161 | port = None | ||
162 | path = None | ||
163 | fragment = None | ||
164 | query = None | ||
165 | |||
166 | # Scheme | ||
167 | if '://' in url: | ||
168 | scheme, url = url.split('://', 1) | ||
169 | |||
170 | # Find the earliest Authority Terminator | ||
171 | # (http://tools.ietf.org/html/rfc3986#section-3.2) | ||
172 | url, path_, delim = split_first(url, ['/', '?', '#']) | ||
173 | |||
174 | if delim: | ||
175 | # Reassemble the path | ||
176 | path = delim + path_ | ||
177 | |||
178 | # Auth | ||
179 | if '@' in url: | ||
180 | # Last '@' denotes end of auth part | ||
181 | auth, url = url.rsplit('@', 1) | ||
182 | |||
183 | # IPv6 | ||
184 | if url and url[0] == '[': | ||
185 | host, url = url.split(']', 1) | ||
186 | host += ']' | ||
187 | |||
188 | # Port | ||
189 | if ':' in url: | ||
190 | _host, port = url.split(':', 1) | ||
191 | |||
192 | if not host: | ||
193 | host = _host | ||
194 | |||
195 | if port: | ||
196 | # If given, ports must be integers. No whitespace, no plus or | ||
197 | # minus prefixes, no non-integer digits such as ^2 (superscript). | ||
198 | if not port.isdigit(): | ||
199 | raise LocationParseError(url) | ||
200 | try: | ||
201 | port = int(port) | ||
202 | except ValueError: | ||
203 | raise LocationParseError(url) | ||
204 | else: | ||
205 | # Blank ports are cool, too. (rfc3986#section-3.2.3) | ||
206 | port = None | ||
207 | |||
208 | elif not host and url: | ||
209 | host = url | ||
210 | |||
211 | if not path: | ||
212 | return Url(scheme, auth, host, port, path, query, fragment) | ||
213 | |||
214 | # Fragment | ||
215 | if '#' in path: | ||
216 | path, fragment = path.split('#', 1) | ||
217 | |||
218 | # Query | ||
219 | if '?' in path: | ||
220 | path, query = path.split('?', 1) | ||
221 | |||
222 | return Url(scheme, auth, host, port, path, query, fragment) | ||
223 | |||
224 | |||
225 | def get_host(url): | ||
226 | """ | ||
227 | Deprecated. Use :func:`parse_url` instead. | ||
228 | """ | ||
229 | p = parse_url(url) | ||
230 | return p.scheme or 'http', p.hostname, p.port | ||