Blob Blame History Raw
From e0f7fcdd554ff42ed065b5362515d90019d36882 Mon Sep 17 00:00:00 2001
From: "Seth M. Larson" <sethmichaellarson@gmail.com>
Date: Fri, 7 Dec 2018 10:19:20 -0600
Subject: [PATCH] urllib3: Implement RFC 3986 URL parsing (#1487)

---
 .../urllib3/packages/rfc3986/__init__.py      |  52 ++
 .../urllib3/packages/rfc3986/abnf_regexp.py   | 188 +++++++
 .../_vendor/urllib3/packages/rfc3986/api.py   |  91 ++++
 .../urllib3/packages/rfc3986/builder.py       | 298 +++++++++++
 .../urllib3/packages/rfc3986/compat.py        |  54 ++
 .../urllib3/packages/rfc3986/exceptions.py    | 111 ++++
 .../_vendor/urllib3/packages/rfc3986/misc.py  | 102 ++++
 .../urllib3/packages/rfc3986/normalizers.py   | 152 ++++++
 .../urllib3/packages/rfc3986/parseresult.py   | 385 ++++++++++++++
 .../_vendor/urllib3/packages/rfc3986/uri.py   | 492 ++++++++++++++++++
 .../urllib3/packages/rfc3986/validators.py    | 428 +++++++++++++++
 src/pip/_vendor/urllib3/util/ssl_.py          |  45 +-
 src/pip/_vendor/urllib3/util/url.py           | 125 ++---
 13 files changed, 2421 insertions(+), 102 deletions(-)
 create mode 100644 src/pip/_vendor/urllib3/packages/rfc3986/__init__.py
 create mode 100644 src/pip/_vendor/urllib3/packages/rfc3986/abnf_regexp.py
 create mode 100644 src/pip/_vendor/urllib3/packages/rfc3986/api.py
 create mode 100644 src/pip/_vendor/urllib3/packages/rfc3986/builder.py
 create mode 100644 src/pip/_vendor/urllib3/packages/rfc3986/compat.py
 create mode 100644 src/pip/_vendor/urllib3/packages/rfc3986/exceptions.py
 create mode 100644 src/pip/_vendor/urllib3/packages/rfc3986/misc.py
 create mode 100644 src/pip/_vendor/urllib3/packages/rfc3986/normalizers.py
 create mode 100644 src/pip/_vendor/urllib3/packages/rfc3986/parseresult.py
 create mode 100644 src/pip/_vendor/urllib3/packages/rfc3986/uri.py
 create mode 100644 src/pip/_vendor/urllib3/packages/rfc3986/validators.py

diff --git a/src/pip/_vendor/urllib3/packages/rfc3986/__init__.py b/src/pip/_vendor/urllib3/packages/rfc3986/__init__.py
new file mode 100644
index 0000000..9719d6f
--- /dev/null
+++ b/src/pip/_vendor/urllib3/packages/rfc3986/__init__.py
@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2014 Rackspace
+# 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.
+
+"""
+An implementation of semantics and validations described in RFC 3986.
+
+See http://rfc3986.readthedocs.io/ for detailed documentation.
+
+:copyright: (c) 2014 Rackspace
+:license: Apache v2.0, see LICENSE for details
+"""
+
+from .api import is_valid_uri
+from .api import normalize_uri
+from .api import uri_reference
+from .api import URIReference
+from .api import urlparse
+from .parseresult import ParseResult
+
+__title__ = 'rfc3986'
+__author__ = 'Ian Stapleton Cordasco'
+__author_email__ = 'graffatcolmingov@gmail.com'
+__license__ = 'Apache v2.0'
+__copyright__ = 'Copyright 2014 Rackspace'
+__version__ = '1.2.0'
+
+__all__ = (
+    'ParseResult',
+    'URIReference',
+    'is_valid_uri',
+    'normalize_uri',
+    'uri_reference',
+    'urlparse',
+    '__title__',
+    '__author__',
+    '__author_email__',
+    '__license__',
+    '__copyright__',
+    '__version__',
+)
diff --git a/src/pip/_vendor/urllib3/packages/rfc3986/abnf_regexp.py b/src/pip/_vendor/urllib3/packages/rfc3986/abnf_regexp.py
new file mode 100644
index 0000000..5b6da17
--- /dev/null
+++ b/src/pip/_vendor/urllib3/packages/rfc3986/abnf_regexp.py
@@ -0,0 +1,188 @@
+# -*- coding: utf-8 -*-
+# 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.
+"""Module for the regular expressions crafted from ABNF."""
+
+# https://tools.ietf.org/html/rfc3986#page-13
+GEN_DELIMS = GENERIC_DELIMITERS = ":/?#[]@"
+GENERIC_DELIMITERS_SET = set(GENERIC_DELIMITERS)
+# https://tools.ietf.org/html/rfc3986#page-13
+SUB_DELIMS = SUB_DELIMITERS = "!$&'()*+,;="
+SUB_DELIMITERS_SET = set(SUB_DELIMITERS)
+# Escape the '*' for use in regular expressions
+SUB_DELIMITERS_RE = r"!$&'()\*+,;="
+RESERVED_CHARS_SET = GENERIC_DELIMITERS_SET.union(SUB_DELIMITERS_SET)
+ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
+DIGIT = '0123456789'
+# https://tools.ietf.org/html/rfc3986#section-2.3
+UNRESERVED = UNRESERVED_CHARS = ALPHA + DIGIT + '._!-'
+UNRESERVED_CHARS_SET = set(UNRESERVED_CHARS)
+NON_PCT_ENCODED_SET = RESERVED_CHARS_SET.union(UNRESERVED_CHARS_SET)
+# We need to escape the '-' in this case:
+UNRESERVED_RE = r'A-Za-z0-9._~\-'
+
+# Percent encoded character values
+PERCENT_ENCODED = PCT_ENCODED = '%[A-Fa-f0-9]{2}'
+PCHAR = '([' + UNRESERVED_RE + SUB_DELIMITERS_RE + ':@]|%s)' % PCT_ENCODED
+
+# NOTE(sigmavirus24): We're going to use more strict regular expressions
+# than appear in Appendix B for scheme. This will prevent over-eager
+# consuming of items that aren't schemes.
+SCHEME_RE = '[a-zA-Z][a-zA-Z0-9+.-]*'
+_AUTHORITY_RE = '[^/?#]*'
+_PATH_RE = '[^?#]*'
+_QUERY_RE = '[^#]*'
+_FRAGMENT_RE = '.*'
+
+# Extracted from http://tools.ietf.org/html/rfc3986#appendix-B
+COMPONENT_PATTERN_DICT = {
+    'scheme': SCHEME_RE,
+    'authority': _AUTHORITY_RE,
+    'path': _PATH_RE,
+    'query': _QUERY_RE,
+    'fragment': _FRAGMENT_RE,
+}
+
+# See http://tools.ietf.org/html/rfc3986#appendix-B
+# In this case, we name each of the important matches so we can use
+# SRE_Match#groupdict to parse the values out if we so choose. This is also
+# modified to ignore other matches that are not important to the parsing of
+# the reference so we can also simply use SRE_Match#groups.
+URL_PARSING_RE = (
+    r'(?:(?P<scheme>{scheme}):)?(?://(?P<authority>{authority}))?'
+    r'(?P<path>{path})(?:\?(?P<query>{query}))?'
+    r'(?:#(?P<fragment>{fragment}))?'
+).format(**COMPONENT_PATTERN_DICT)
+
+
+# #########################
+# Authority Matcher Section
+# #########################
+
+# Host patterns, see: http://tools.ietf.org/html/rfc3986#section-3.2.2
+# The pattern for a regular name, e.g.,  www.google.com, api.github.com
+REGULAR_NAME_RE = REG_NAME = '((?:{0}|[{1}])*)'.format(
+    '%[0-9A-Fa-f]{2}', SUB_DELIMITERS_RE + UNRESERVED_RE
+)
+# The pattern for an IPv4 address, e.g., 192.168.255.255, 127.0.0.1,
+IPv4_RE = '([0-9]{1,3}.){3}[0-9]{1,3}'
+# Hexadecimal characters used in each piece of an IPv6 address
+HEXDIG_RE = '[0-9A-Fa-f]{1,4}'
+# Least-significant 32 bits of an IPv6 address
+LS32_RE = '({hex}:{hex}|{ipv4})'.format(hex=HEXDIG_RE, ipv4=IPv4_RE)
+# Substitutions into the following patterns for IPv6 patterns defined
+# http://tools.ietf.org/html/rfc3986#page-20
+_subs = {'hex': HEXDIG_RE, 'ls32': LS32_RE}
+
+# Below: h16 = hexdig, see: https://tools.ietf.org/html/rfc5234 for details
+# about ABNF (Augmented Backus-Naur Form) use in the comments
+variations = [
+    #                            6( h16 ":" ) ls32
+    '(%(hex)s:){6}%(ls32)s' % _subs,
+    #                       "::" 5( h16 ":" ) ls32
+    '::(%(hex)s:){5}%(ls32)s' % _subs,
+    # [               h16 ] "::" 4( h16 ":" ) ls32
+    '(%(hex)s)?::(%(hex)s:){4}%(ls32)s' % _subs,
+    # [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
+    '((%(hex)s:)?%(hex)s)?::(%(hex)s:){3}%(ls32)s' % _subs,
+    # [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
+    '((%(hex)s:){0,2}%(hex)s)?::(%(hex)s:){2}%(ls32)s' % _subs,
+    # [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
+    '((%(hex)s:){0,3}%(hex)s)?::%(hex)s:%(ls32)s' % _subs,
+    # [ *4( h16 ":" ) h16 ] "::"              ls32
+    '((%(hex)s:){0,4}%(hex)s)?::%(ls32)s' % _subs,
+    # [ *5( h16 ":" ) h16 ] "::"              h16
+    '((%(hex)s:){0,5}%(hex)s)?::%(hex)s' % _subs,
+    # [ *6( h16 ":" ) h16 ] "::"
+    '((%(hex)s:){0,6}%(hex)s)?::' % _subs,
+]
+
+IPv6_RE = '(({0})|({1})|({2})|({3})|({4})|({5})|({6})|({7})|({8}))'.format(
+    *variations
+)
+
+IPv_FUTURE_RE = 'v[0-9A-Fa-f]+.[%s]+' % (
+    UNRESERVED_RE + SUB_DELIMITERS_RE + ':'
+)
+
+
+# RFC 6874 Zone ID ABNF
+ZONE_ID = '(?:[' + UNRESERVED_RE + ']|' + PCT_ENCODED + ')+'
+IPv6_ADDRZ_RE = IPv6_RE + '%25' + ZONE_ID
+
+IP_LITERAL_RE = r'\[({0}|(?:{1})|{2})\]'.format(
+    IPv6_RE,
+    IPv6_ADDRZ_RE,
+    IPv_FUTURE_RE,
+)
+
+# Pattern for matching the host piece of the authority
+HOST_RE = HOST_PATTERN = '({0}|{1}|{2})'.format(
+    REG_NAME,
+    IPv4_RE,
+    IP_LITERAL_RE,
+)
+USERINFO_RE = '^([' + UNRESERVED_RE + SUB_DELIMITERS_RE + ':]|%s)+' % (
+    PCT_ENCODED
+)
+PORT_RE = '[0-9]{1,5}'
+
+# ####################
+# Path Matcher Section
+# ####################
+
+# See http://tools.ietf.org/html/rfc3986#section-3.3 for more information
+# about the path patterns defined below.
+segments = {
+    'segment': PCHAR + '*',
+    # Non-zero length segment
+    'segment-nz': PCHAR + '+',
+    # Non-zero length segment without ":"
+    'segment-nz-nc': PCHAR.replace(':', '') + '+'
+}
+
+# Path types taken from Section 3.3 (linked above)
+PATH_EMPTY = '^$'
+PATH_ROOTLESS = '%(segment-nz)s(/%(segment)s)*' % segments
+PATH_NOSCHEME = '%(segment-nz-nc)s(/%(segment)s)*' % segments
+PATH_ABSOLUTE = '/(%s)?' % PATH_ROOTLESS
+PATH_ABEMPTY = '(/%(segment)s)*' % segments
+PATH_RE = '^(%s|%s|%s|%s|%s)$' % (
+    PATH_ABEMPTY, PATH_ABSOLUTE, PATH_NOSCHEME, PATH_ROOTLESS, PATH_EMPTY
+)
+
+FRAGMENT_RE = QUERY_RE = (
+    '^([/?:@' + UNRESERVED_RE + SUB_DELIMITERS_RE + ']|%s)*$' % PCT_ENCODED
+)
+
+# ##########################
+# Relative reference matcher
+# ##########################
+
+# See http://tools.ietf.org/html/rfc3986#section-4.2 for details
+RELATIVE_PART_RE = '(//%s%s|%s|%s|%s)' % (
+    COMPONENT_PATTERN_DICT['authority'],
+    PATH_ABEMPTY,
+    PATH_ABSOLUTE,
+    PATH_NOSCHEME,
+    PATH_EMPTY,
+)
+
+# See http://tools.ietf.org/html/rfc3986#section-3 for definition
+HIER_PART_RE = '(//%s%s|%s|%s|%s)' % (
+    COMPONENT_PATTERN_DICT['authority'],
+    PATH_ABEMPTY,
+    PATH_ABSOLUTE,
+    PATH_ROOTLESS,
+    PATH_EMPTY,
+)
diff --git a/src/pip/_vendor/urllib3/packages/rfc3986/api.py b/src/pip/_vendor/urllib3/packages/rfc3986/api.py
new file mode 100644
index 0000000..17f4daf
--- /dev/null
+++ b/src/pip/_vendor/urllib3/packages/rfc3986/api.py
@@ -0,0 +1,91 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2014 Rackspace
+# 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.
+"""
+Module containing the simple and functional API for rfc3986.
+
+This module defines functions and provides access to the public attributes
+and classes of rfc3986.
+"""
+
+from .parseresult import ParseResult
+from .uri import URIReference
+
+
+def uri_reference(uri, encoding='utf-8'):
+    """Parse a URI string into a URIReference.
+
+    This is a convenience function. You could achieve the same end by using
+    ``URIReference.from_string(uri)``.
+
+    :param str uri: The URI which needs to be parsed into a reference.
+    :param str encoding: The encoding of the string provided
+    :returns: A parsed URI
+    :rtype: :class:`URIReference`
+    """
+    return URIReference.from_string(uri, encoding)
+
+
+def is_valid_uri(uri, encoding='utf-8', **kwargs):
+    """Determine if the URI given is valid.
+
+    This is a convenience function. You could use either
+    ``uri_reference(uri).is_valid()`` or
+    ``URIReference.from_string(uri).is_valid()`` to achieve the same result.
+
+    :param str uri: The URI to be validated.
+    :param str encoding: The encoding of the string provided
+    :param bool require_scheme: Set to ``True`` if you wish to require the
+        presence of the scheme component.
+    :param bool require_authority: Set to ``True`` if you wish to require the
+        presence of the authority component.
+    :param bool require_path: Set to ``True`` if you wish to require the
+        presence of the path component.
+    :param bool require_query: Set to ``True`` if you wish to require the
+        presence of the query component.
+    :param bool require_fragment: Set to ``True`` if you wish to require the
+        presence of the fragment component.
+    :returns: ``True`` if the URI is valid, ``False`` otherwise.
+    :rtype: bool
+    """
+    return URIReference.from_string(uri, encoding).is_valid(**kwargs)
+
+
+def normalize_uri(uri, encoding='utf-8'):
+    """Normalize the given URI.
+
+    This is a convenience function. You could use either
+    ``uri_reference(uri).normalize().unsplit()`` or
+    ``URIReference.from_string(uri).normalize().unsplit()`` instead.
+
+    :param str uri: The URI to be normalized.
+    :param str encoding: The encoding of the string provided
+    :returns: The normalized URI.
+    :rtype: str
+    """
+    normalized_reference = URIReference.from_string(uri, encoding).normalize()
+    return normalized_reference.unsplit()
+
+
+def urlparse(uri, encoding='utf-8'):
+    """Parse a given URI and return a ParseResult.
+
+    This is a partial replacement of the standard library's urlparse function.
+
+    :param str uri: The URI to be parsed.
+    :param str encoding: The encoding of the string provided.
+    :returns: A parsed URI
+    :rtype: :class:`~rfc3986.parseresult.ParseResult`
+    """
+    return ParseResult.from_string(uri, encoding, strict=False)
diff --git a/src/pip/_vendor/urllib3/packages/rfc3986/builder.py b/src/pip/_vendor/urllib3/packages/rfc3986/builder.py
new file mode 100644
index 0000000..7934279
--- /dev/null
+++ b/src/pip/_vendor/urllib3/packages/rfc3986/builder.py
@@ -0,0 +1,298 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017 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.
+"""Module containing the logic for the URIBuilder object."""
+from . import compat
+from . import normalizers
+from . import uri
+
+
+class URIBuilder(object):
+    """Object to aid in building up a URI Reference from parts.
+
+    .. note::
+
+        This object should be instantiated by the user, but it's recommended
+        that it is not provided with arguments. Instead, use the available
+        method to populate the fields.
+
+    """
+
+    def __init__(self, scheme=None, userinfo=None, host=None, port=None,
+                 path=None, query=None, fragment=None):
+        """Initialize our URI builder.
+
+        :param str scheme:
+            (optional)
+        :param str userinfo:
+            (optional)
+        :param str host:
+            (optional)
+        :param int port:
+            (optional)
+        :param str path:
+            (optional)
+        :param str query:
+            (optional)
+        :param str fragment:
+            (optional)
+        """
+        self.scheme = scheme
+        self.userinfo = userinfo
+        self.host = host
+        self.port = port
+        self.path = path
+        self.query = query
+        self.fragment = fragment
+
+    def __repr__(self):
+        """Provide a convenient view of our builder object."""
+        formatstr = ('URIBuilder(scheme={b.scheme}, userinfo={b.userinfo}, '
+                     'host={b.host}, port={b.port}, path={b.path}, '
+                     'query={b.query}, fragment={b.fragment})')
+        return formatstr.format(b=self)
+
+    def add_scheme(self, scheme):
+        """Add a scheme to our builder object.
+
+        After normalizing, this will generate a new URIBuilder instance with
+        the specified scheme and all other attributes the same.
+
+        .. code-block:: python
+
+            >>> URIBuilder().add_scheme('HTTPS')
+            URIBuilder(scheme='https', userinfo=None, host=None, port=None,
+                    path=None, query=None, fragment=None)
+
+        """
+        scheme = normalizers.normalize_scheme(scheme)
+        return URIBuilder(
+            scheme=scheme,
+            userinfo=self.userinfo,
+            host=self.host,
+            port=self.port,
+            path=self.path,
+            query=self.query,
+            fragment=self.fragment,
+        )
+
+    def add_credentials(self, username, password):
+        """Add credentials as the userinfo portion of the URI.
+
+        .. code-block:: python
+
+            >>> URIBuilder().add_credentials('root', 's3crete')
+            URIBuilder(scheme=None, userinfo='root:s3crete', host=None,
+                    port=None, path=None, query=None, fragment=None)
+
+            >>> URIBuilder().add_credentials('root', None)
+            URIBuilder(scheme=None, userinfo='root', host=None,
+                    port=None, path=None, query=None, fragment=None)
+        """
+        if username is None:
+            raise ValueError('Username cannot be None')
+        userinfo = normalizers.normalize_username(username)
+
+        if password is not None:
+            userinfo = '{}:{}'.format(
+                userinfo,
+                normalizers.normalize_password(password),
+            )
+
+        return URIBuilder(
+            scheme=self.scheme,
+            userinfo=userinfo,
+            host=self.host,
+            port=self.port,
+            path=self.path,
+            query=self.query,
+            fragment=self.fragment,
+        )
+
+    def add_host(self, host):
+        """Add hostname to the URI.
+
+        .. code-block:: python
+
+            >>> URIBuilder().add_host('google.com')
+            URIBuilder(scheme=None, userinfo=None, host='google.com',
+                    port=None, path=None, query=None, fragment=None)
+
+        """
+        return URIBuilder(
+            scheme=self.scheme,
+            userinfo=self.userinfo,
+            host=normalizers.normalize_host(host),
+            port=self.port,
+            path=self.path,
+            query=self.query,
+            fragment=self.fragment,
+        )
+
+    def add_port(self, port):
+        """Add port to the URI.
+
+        .. code-block:: python
+
+            >>> URIBuilder().add_port(80)
+            URIBuilder(scheme=None, userinfo=None, host=None, port='80',
+                    path=None, query=None, fragment=None)
+
+            >>> URIBuilder().add_port(443)
+            URIBuilder(scheme=None, userinfo=None, host=None, port='443',
+                    path=None, query=None, fragment=None)
+
+        """
+        port_int = int(port)
+        if port_int < 0:
+            raise ValueError(
+                'ports are not allowed to be negative. You provided {}'.format(
+                    port_int,
+                )
+            )
+        if port_int > 65535:
+            raise ValueError(
+                'ports are not allowed to be larger than 65535. '
+                'You provided {}'.format(
+                    port_int,
+                )
+            )
+
+        return URIBuilder(
+            scheme=self.scheme,
+            userinfo=self.userinfo,
+            host=self.host,
+            port='{}'.format(port_int),
+            path=self.path,
+            query=self.query,
+            fragment=self.fragment,
+        )
+
+    def add_path(self, path):
+        """Add a path to the URI.
+
+        .. code-block:: python
+
+            >>> URIBuilder().add_path('sigmavirus24/rfc3985')
+            URIBuilder(scheme=None, userinfo=None, host=None, port=None,
+                    path='/sigmavirus24/rfc3986', query=None, fragment=None)
+
+            >>> URIBuilder().add_path('/checkout.php')
+            URIBuilder(scheme=None, userinfo=None, host=None, port=None,
+                    path='/checkout.php', query=None, fragment=None)
+
+        """
+        if not path.startswith('/'):
+            path = '/{}'.format(path)
+
+        return URIBuilder(
+            scheme=self.scheme,
+            userinfo=self.userinfo,
+            host=self.host,
+            port=self.port,
+            path=normalizers.normalize_path(path),
+            query=self.query,
+            fragment=self.fragment,
+        )
+
+    def add_query_from(self, query_items):
+        """Generate and add a query a dictionary or list of tuples.
+
+        .. code-block:: python
+
+            >>> URIBuilder().add_query_from({'a': 'b c'})
+            URIBuilder(scheme=None, userinfo=None, host=None, port=None,
+                    path=None, query='a=b+c', fragment=None)
+
+            >>> URIBuilder().add_query_from([('a', 'b c')])
+            URIBuilder(scheme=None, userinfo=None, host=None, port=None,
+                    path=None, query='a=b+c', fragment=None)
+
+        """
+        query = normalizers.normalize_query(compat.urlencode(query_items))
+
+        return URIBuilder(
+            scheme=self.scheme,
+            userinfo=self.userinfo,
+            host=self.host,
+            port=self.port,
+            path=self.path,
+            query=query,
+            fragment=self.fragment,
+        )
+
+    def add_query(self, query):
+        """Add a pre-formated query string to the URI.
+
+        .. code-block:: python
+
+            >>> URIBuilder().add_query('a=b&c=d')
+            URIBuilder(scheme=None, userinfo=None, host=None, port=None,
+                    path=None, query='a=b&c=d', fragment=None)
+
+        """
+        return URIBuilder(
+            scheme=self.scheme,
+            userinfo=self.userinfo,
+            host=self.host,
+            port=self.port,
+            path=self.path,
+            query=normalizers.normalize_query(query),
+            fragment=self.fragment,
+        )
+
+    def add_fragment(self, fragment):
+        """Add a fragment to the URI.
+
+        .. code-block:: python
+
+            >>> URIBuilder().add_fragment('section-2.6.1')
+            URIBuilder(scheme=None, userinfo=None, host=None, port=None,
+                    path=None, query=None, fragment='section-2.6.1')
+
+        """
+        return URIBuilder(
+            scheme=self.scheme,
+            userinfo=self.userinfo,
+            host=self.host,
+            port=self.port,
+            path=self.path,
+            query=self.query,
+            fragment=normalizers.normalize_fragment(fragment),
+        )
+
+    def finalize(self):
+        """Create a URIReference from our builder.
+
+        .. code-block:: python
+
+            >>> URIBuilder().add_scheme('https').add_host('github.com'
+            ...     ).add_path('sigmavirus24/rfc3986').finalize().unsplit()
+            'https://github.com/sigmavirus24/rfc3986'
+
+            >>> URIBuilder().add_scheme('https').add_host('github.com'
+            ...     ).add_path('sigmavirus24/rfc3986').add_credentials(
+            ...     'sigmavirus24', 'not-re@l').finalize().unsplit()
+            'https://sigmavirus24:not-re%40l@github.com/sigmavirus24/rfc3986'
+
+        """
+        return uri.URIReference(
+            self.scheme,
+            normalizers.normalize_authority(
+                (self.userinfo, self.host, self.port)
+            ),
+            self.path,
+            self.query,
+            self.fragment,
+        )
diff --git a/src/pip/_vendor/urllib3/packages/rfc3986/compat.py b/src/pip/_vendor/urllib3/packages/rfc3986/compat.py
new file mode 100644
index 0000000..8968c38
--- /dev/null
+++ b/src/pip/_vendor/urllib3/packages/rfc3986/compat.py
@@ -0,0 +1,54 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2014 Rackspace
+# 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.
+"""Compatibility module for Python 2 and 3 support."""
+import sys
+
+try:
+    from urllib.parse import quote as urlquote
+except ImportError:  # Python 2.x
+    from urllib import quote as urlquote
+
+try:
+    from urllib.parse import urlencode
+except ImportError:  # Python 2.x
+    from urllib import urlencode
+
+__all__ = (
+    'to_bytes',
+    'to_str',
+    'urlquote',
+    'urlencode',
+)
+
+PY3 = (3, 0) <= sys.version_info < (4, 0)
+PY2 = (2, 6) <= sys.version_info < (2, 8)
+
+
+if PY3:
+    unicode = str  # Python 3.x
+
+
+def to_str(b, encoding='utf-8'):
+    """Ensure that b is text in the specified encoding."""
+    if hasattr(b, 'decode') and not isinstance(b, unicode):
+        b = b.decode(encoding)
+    return b
+
+
+def to_bytes(s, encoding='utf-8'):
+    """Ensure that s is converted to bytes from the encoding."""
+    if hasattr(s, 'encode') and not isinstance(s, bytes):
+        s = s.encode(encoding)
+    return s
diff --git a/src/pip/_vendor/urllib3/packages/rfc3986/exceptions.py b/src/pip/_vendor/urllib3/packages/rfc3986/exceptions.py
new file mode 100644
index 0000000..e0886a5
--- /dev/null
+++ b/src/pip/_vendor/urllib3/packages/rfc3986/exceptions.py
@@ -0,0 +1,111 @@
+# -*- coding: utf-8 -*-
+"""Exceptions module for rfc3986."""
+
+
+class RFC3986Exception(Exception):
+    """Base class for all rfc3986 exception classes."""
+
+    pass
+
+
+class InvalidAuthority(RFC3986Exception):
+    """Exception when the authority string is invalid."""
+
+    def __init__(self, authority):
+        """Initialize the exception with the invalid authority."""
+        super(InvalidAuthority, self).__init__(
+            "The authority ({0}) is not valid.".format(authority))
+
+
+class InvalidPort(RFC3986Exception):
+    """Exception when the port is invalid."""
+
+    def __init__(self, port):
+        """Initialize the exception with the invalid port."""
+        super(InvalidPort, self).__init__(
+            'The port ("{0}") is not valid.'.format(port))
+
+
+class ResolutionError(RFC3986Exception):
+    """Exception to indicate a failure to resolve a URI."""
+
+    def __init__(self, uri):
+        """Initialize the error with the failed URI."""
+        super(ResolutionError, self).__init__(
+            "{0} is not an absolute URI.".format(uri.unsplit()))
+
+
+class ValidationError(RFC3986Exception):
+    """Exception raised during Validation of a URI."""
+
+    pass
+
+
+class MissingComponentError(ValidationError):
+    """Exception raised when a required component is missing."""
+
+    def __init__(self, uri, *component_names):
+        """Initialize the error with the missing component name."""
+        verb = 'was'
+        if len(component_names) > 1:
+            verb = 'were'
+
+        self.uri = uri
+        self.components = sorted(component_names)
+        components = ', '.join(self.components)
+        super(MissingComponentError, self).__init__(
+            "{} {} required but missing".format(components, verb),
+            uri,
+            self.components,
+        )
+
+
+class UnpermittedComponentError(ValidationError):
+    """Exception raised when a component has an unpermitted value."""
+
+    def __init__(self, component_name, component_value, allowed_values):
+        """Initialize the error with the unpermitted component."""
+        super(UnpermittedComponentError, self).__init__(
+            "{} was required to be one of {!r} but was {!r}".format(
+                component_name, list(sorted(allowed_values)), component_value,
+            ),
+            component_name,
+            component_value,
+            allowed_values,
+        )
+        self.component_name = component_name
+        self.component_value = component_value
+        self.allowed_values = allowed_values
+
+
+class PasswordForbidden(ValidationError):
+    """Exception raised when a URL has a password in the userinfo section."""
+
+    def __init__(self, uri):
+        """Initialize the error with the URI that failed validation."""
+        unsplit = getattr(uri, 'unsplit', lambda: uri)
+        super(PasswordForbidden, self).__init__(
+            '"{}" contained a password when validation forbade it'.format(
+                unsplit()
+            )
+        )
+        self.uri = uri
+
+
+class InvalidComponentsError(ValidationError):
+    """Exception raised when one or more components are invalid."""
+
+    def __init__(self, uri, *component_names):
+        """Initialize the error with the invalid component name(s)."""
+        verb = 'was'
+        if len(component_names) > 1:
+            verb = 'were'
+
+        self.uri = uri
+        self.components = sorted(component_names)
+        components = ', '.join(self.components)
+        super(InvalidComponentsError, self).__init__(
+            "{} {} found to be invalid".format(components, verb),
+            uri,
+            self.components,
+        )
diff --git a/src/pip/_vendor/urllib3/packages/rfc3986/misc.py b/src/pip/_vendor/urllib3/packages/rfc3986/misc.py
new file mode 100644
index 0000000..697039a
--- /dev/null
+++ b/src/pip/_vendor/urllib3/packages/rfc3986/misc.py
@@ -0,0 +1,102 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2014 Rackspace
+# 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.
+"""
+Module containing compiled regular expressions and constants.
+
+This module contains important constants, patterns, and compiled regular
+expressions for parsing and validating URIs and their components.
+"""
+
+import re
+
+from . import abnf_regexp
+
+# These are enumerated for the named tuple used as a superclass of
+# URIReference
+URI_COMPONENTS = ['scheme', 'authority', 'path', 'query', 'fragment']
+
+important_characters = {
+    'generic_delimiters': abnf_regexp.GENERIC_DELIMITERS,
+    'sub_delimiters': abnf_regexp.SUB_DELIMITERS,
+    # We need to escape the '*' in this case
+    're_sub_delimiters': abnf_regexp.SUB_DELIMITERS_RE,
+    'unreserved_chars': abnf_regexp.UNRESERVED_CHARS,
+    # We need to escape the '-' in this case:
+    're_unreserved': abnf_regexp.UNRESERVED_RE,
+}
+
+# For details about delimiters and reserved characters, see:
+# http://tools.ietf.org/html/rfc3986#section-2.2
+GENERIC_DELIMITERS = abnf_regexp.GENERIC_DELIMITERS_SET
+SUB_DELIMITERS = abnf_regexp.SUB_DELIMITERS_SET
+RESERVED_CHARS = abnf_regexp.RESERVED_CHARS_SET
+# For details about unreserved characters, see:
+# http://tools.ietf.org/html/rfc3986#section-2.3
+UNRESERVED_CHARS = abnf_regexp.UNRESERVED_CHARS_SET
+NON_PCT_ENCODED = abnf_regexp.NON_PCT_ENCODED_SET
+
+URI_MATCHER = re.compile(abnf_regexp.URL_PARSING_RE)
+
+SUBAUTHORITY_MATCHER = re.compile((
+    '^(?:(?P<userinfo>{0})@)?'  # userinfo
+    '(?P<host>{1})'  # host
+    ':?(?P<port>{2})?$'  # port
+    ).format(abnf_regexp.USERINFO_RE,
+             abnf_regexp.HOST_PATTERN,
+             abnf_regexp.PORT_RE))
+
+
+IPv4_MATCHER = re.compile('^' + abnf_regexp.IPv4_RE + '$')
+
+# Matcher used to validate path components
+PATH_MATCHER = re.compile(abnf_regexp.PATH_RE)
+
+
+# ##################################
+# Query and Fragment Matcher Section
+# ##################################
+
+QUERY_MATCHER = re.compile(abnf_regexp.QUERY_RE)
+
+FRAGMENT_MATCHER = QUERY_MATCHER
+
+# Scheme validation, see: http://tools.ietf.org/html/rfc3986#section-3.1
+SCHEME_MATCHER = re.compile('^{0}$'.format(abnf_regexp.SCHEME_RE))
+
+RELATIVE_REF_MATCHER = re.compile(r'^%s(\?%s)?(#%s)?$' % (
+    abnf_regexp.RELATIVE_PART_RE, abnf_regexp.QUERY_RE,
+    abnf_regexp.FRAGMENT_RE,
+))
+
+# See http://tools.ietf.org/html/rfc3986#section-4.3
+ABSOLUTE_URI_MATCHER = re.compile(r'^%s:%s(\?%s)?$' % (
+    abnf_regexp.COMPONENT_PATTERN_DICT['scheme'],
+    abnf_regexp.HIER_PART_RE,
+    abnf_regexp.QUERY_RE[1:-1],
+))
+
+
+# Path merger as defined in http://tools.ietf.org/html/rfc3986#section-5.2.3
+def merge_paths(base_uri, relative_path):
+    """Merge a base URI's path with a relative URI's path."""
+    if base_uri.path is None and base_uri.authority is not None:
+        return '/' + relative_path
+    else:
+        path = base_uri.path or ''
+        index = path.rfind('/')
+        return path[:index] + '/' + relative_path
+
+
+UseExisting = object()
diff --git a/src/pip/_vendor/urllib3/packages/rfc3986/normalizers.py b/src/pip/_vendor/urllib3/packages/rfc3986/normalizers.py
new file mode 100644
index 0000000..ea6c6e1
--- /dev/null
+++ b/src/pip/_vendor/urllib3/packages/rfc3986/normalizers.py
@@ -0,0 +1,152 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2014 Rackspace
+# 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.
+"""Module with functions to normalize components."""
+import re
+
+from . import compat
+from . import misc
+
+
+def normalize_scheme(scheme):
+    """Normalize the scheme component."""
+    return scheme.lower()
+
+
+def normalize_authority(authority):
+    """Normalize an authority tuple to a string."""
+    userinfo, host, port = authority
+    result = ''
+    if userinfo:
+        result += normalize_percent_characters(userinfo) + '@'
+    if host:
+        result += normalize_host(host)
+    if port:
+        result += ':' + port
+    return result
+
+
+def normalize_username(username):
+    """Normalize a username to make it safe to include in userinfo."""
+    return compat.urlquote(username)
+
+
+def normalize_password(password):
+    """Normalize a password to make safe for userinfo."""
+    return compat.urlquote(password)
+
+
+def normalize_host(host):
+    """Normalize a host string."""
+    return host.lower()
+
+
+def normalize_path(path):
+    """Normalize the path string."""
+    if not path:
+        return path
+
+    path = normalize_percent_characters(path)
+    return remove_dot_segments(path)
+
+
+def normalize_query(query):
+    """Normalize the query string."""
+    if not query:
+        return query
+    return normalize_percent_characters(query)
+
+
+def normalize_fragment(fragment):
+    """Normalize the fragment string."""
+    if not fragment:
+        return fragment
+    return normalize_percent_characters(fragment)
+
+
+PERCENT_MATCHER = re.compile('%[A-Fa-f0-9]{2}')
+
+
+def normalize_percent_characters(s):
+    """All percent characters should be upper-cased.
+
+    For example, ``"%3afoo%DF%ab"`` should be turned into ``"%3Afoo%DF%AB"``.
+    """
+    matches = set(PERCENT_MATCHER.findall(s))
+    for m in matches:
+        if not m.isupper():
+            s = s.replace(m, m.upper())
+    return s
+
+
+def remove_dot_segments(s):
+    """Remove dot segments from the string.
+
+    See also Section 5.2.4 of :rfc:`3986`.
+    """
+    # See http://tools.ietf.org/html/rfc3986#section-5.2.4 for pseudo-code
+    segments = s.split('/')  # Turn the path into a list of segments
+    output = []  # Initialize the variable to use to store output
+
+    for segment in segments:
+        # '.' is the current directory, so ignore it, it is superfluous
+        if segment == '.':
+            continue
+        # Anything other than '..', should be appended to the output
+        elif segment != '..':
+            output.append(segment)
+        # In this case segment == '..', if we can, we should pop the last
+        # element
+        elif output:
+            output.pop()
+
+    # If the path starts with '/' and the output is empty or the first string
+    # is non-empty
+    if s.startswith('/') and (not output or output[0]):
+        output.insert(0, '')
+
+    # If the path starts with '/.' or '/..' ensure we add one more empty
+    # string to add a trailing '/'
+    if s.endswith(('/.', '/..')):
+        output.append('')
+
+    return '/'.join(output)
+
+
+def encode_component(uri_component, encoding):
+    """Encode the specific component in the provided encoding."""
+    if uri_component is None:
+        return uri_component
+
+    # Try to see if the component we're encoding is already percent-encoded
+    # so we can skip all '%' characters but still encode all others.
+    percent_encodings = len(PERCENT_MATCHER.findall(
+                            compat.to_str(uri_component, encoding)))
+
+    uri_bytes = compat.to_bytes(uri_component, encoding)
+    is_percent_encoded = percent_encodings == uri_bytes.count(b'%')
+
+    encoded_uri = bytearray()
+
+    for i in range(0, len(uri_bytes)):
+        # Will return a single character bytestring on both Python 2 & 3
+        byte = uri_bytes[i:i+1]
+        byte_ord = ord(byte)
+        if ((is_percent_encoded and byte == b'%')
+                or (byte_ord < 128 and byte.decode() in misc.NON_PCT_ENCODED)):
+            encoded_uri.extend(byte)
+            continue
+        encoded_uri.extend('%{0:02x}'.format(byte_ord).encode())
+
+    return encoded_uri.decode(encoding)
diff --git a/src/pip/_vendor/urllib3/packages/rfc3986/parseresult.py b/src/pip/_vendor/urllib3/packages/rfc3986/parseresult.py
new file mode 100644
index 0000000..0a73456
--- /dev/null
+++ b/src/pip/_vendor/urllib3/packages/rfc3986/parseresult.py
@@ -0,0 +1,385 @@
+# -*- coding: utf-8 -*-
+# 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.
+"""Module containing the urlparse compatibility logic."""
+from collections import namedtuple
+
+from . import compat
+from . import exceptions
+from . import misc
+from . import normalizers
+from . import uri
+
+__all__ = ('ParseResult', 'ParseResultBytes')
+
+PARSED_COMPONENTS = ('scheme', 'userinfo', 'host', 'port', 'path', 'query',
+                     'fragment')
+
+
+class ParseResultMixin(object):
+    def _generate_authority(self, attributes):
+        # I swear I did not align the comparisons below. That's just how they
+        # happened to align based on pep8 and attribute lengths.
+        userinfo, host, port = (attributes[p]
+                                for p in ('userinfo', 'host', 'port'))
+        if (self.userinfo != userinfo or
+                self.host != host or
+                self.port != port):
+            if port:
+                port = '{0}'.format(port)
+            return normalizers.normalize_authority(
+                (compat.to_str(userinfo, self.encoding),
+                 compat.to_str(host, self.encoding),
+                 port)
+            )
+        return self.authority
+
+    def geturl(self):
+        """Shim to match the standard library method."""
+        return self.unsplit()
+
+    @property
+    def hostname(self):
+        """Shim to match the standard library."""
+        return self.host
+
+    @property
+    def netloc(self):
+        """Shim to match the standard library."""
+        return self.authority
+
+    @property
+    def params(self):
+        """Shim to match the standard library."""
+        return self.query
+
+
+class ParseResult(namedtuple('ParseResult', PARSED_COMPONENTS),
+                  ParseResultMixin):
+    """Implementation of urlparse compatibility class.
+
+    This uses the URIReference logic to handle compatibility with the
+    urlparse.ParseResult class.
+    """
+
+    slots = ()
+
+    def __new__(cls, scheme, userinfo, host, port, path, query, fragment,
+                uri_ref, encoding='utf-8'):
+        """Create a new ParseResult."""
+        parse_result = super(ParseResult, cls).__new__(
+            cls,
+            scheme or None,
+            userinfo or None,
+            host,
+            port or None,
+            path or None,
+            query,
+            fragment)
+        parse_result.encoding = encoding
+        parse_result.reference = uri_ref
+        return parse_result
+
+    @classmethod
+    def from_parts(cls, scheme=None, userinfo=None, host=None, port=None,
+                   path=None, query=None, fragment=None, encoding='utf-8'):
+        """Create a ParseResult instance from its parts."""
+        authority = ''
+        if userinfo is not None:
+            authority += userinfo + '@'
+        if host is not None:
+            authority += host
+        if port is not None:
+            authority += ':{0}'.format(port)
+        uri_ref = uri.URIReference(scheme=scheme,
+                                   authority=authority,
+                                   path=path,
+                                   query=query,
+                                   fragment=fragment,
+                                   encoding=encoding).normalize()
+        userinfo, host, port = authority_from(uri_ref, strict=True)
+        return cls(scheme=uri_ref.scheme,
+                   userinfo=userinfo,
+                   host=host,
+                   port=port,
+                   path=uri_ref.path,
+                   query=uri_ref.query,
+                   fragment=uri_ref.fragment,
+                   uri_ref=uri_ref,
+                   encoding=encoding)
+
+    @classmethod
+    def from_string(cls, uri_string, encoding='utf-8', strict=True,
+                    lazy_normalize=True):
+        """Parse a URI 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
+        :param bool strict: Parse strictly according to :rfc:`3986` if True.
+            If False, parse similarly to the standard library's urlparse
+            function.
+        :returns: :class:`ParseResult` or subclass thereof
+        """
+        reference = uri.URIReference.from_string(uri_string, encoding)
+        if not lazy_normalize:
+            reference = reference.normalize()
+        userinfo, host, port = authority_from(reference, strict)
+
+        return cls(scheme=reference.scheme,
+                   userinfo=userinfo,
+                   host=host,
+                   port=port,
+                   path=reference.path,
+                   query=reference.query,
+                   fragment=reference.fragment,
+                   uri_ref=reference,
+                   encoding=encoding)
+
+    @property
+    def authority(self):
+        """Return the normalized authority."""
+        return self.reference.authority
+
+    def copy_with(self, scheme=misc.UseExisting, userinfo=misc.UseExisting,
+                  host=misc.UseExisting, port=misc.UseExisting,
+                  path=misc.UseExisting, query=misc.UseExisting,
+                  fragment=misc.UseExisting):
+        """Create a copy of this instance replacing with specified parts."""
+        attributes = zip(PARSED_COMPONENTS,
+                         (scheme, userinfo, host, port, path, query, fragment))
+        attrs_dict = {}
+        for name, value in attributes:
+            if value is misc.UseExisting:
+                value = getattr(self, name)
+            attrs_dict[name] = value
+        authority = self._generate_authority(attrs_dict)
+        ref = self.reference.copy_with(scheme=attrs_dict['scheme'],
+                                       authority=authority,
+                                       path=attrs_dict['path'],
+                                       query=attrs_dict['query'],
+                                       fragment=attrs_dict['fragment'])
+        return ParseResult(uri_ref=ref, encoding=self.encoding, **attrs_dict)
+
+    def encode(self, encoding=None):
+        """Convert to an instance of ParseResultBytes."""
+        encoding = encoding or self.encoding
+        attrs = dict(
+            zip(PARSED_COMPONENTS,
+                (attr.encode(encoding) if hasattr(attr, 'encode') else attr
+                 for attr in self)))
+        return ParseResultBytes(
+            uri_ref=self.reference,
+            encoding=encoding,
+            **attrs
+        )
+
+    def unsplit(self, use_idna=False):
+        """Create a URI string from the components.
+
+        :returns: The parsed URI reconstituted as a string.
+        :rtype: str
+        """
+        parse_result = self
+        if use_idna and self.host:
+            hostbytes = self.host.encode('idna')
+            host = hostbytes.decode(self.encoding)
+            parse_result = self.copy_with(host=host)
+        return parse_result.reference.unsplit()
+
+
+class ParseResultBytes(namedtuple('ParseResultBytes', PARSED_COMPONENTS),
+                       ParseResultMixin):
+    """Compatibility shim for the urlparse.ParseResultBytes object."""
+
+    def __new__(cls, scheme, userinfo, host, port, path, query, fragment,
+                uri_ref, encoding='utf-8', lazy_normalize=True):
+        """Create a new ParseResultBytes instance."""
+        parse_result = super(ParseResultBytes, cls).__new__(
+            cls,
+            scheme or None,
+            userinfo or None,
+            host,
+            port or None,
+            path or None,
+            query or None,
+            fragment or None)
+        parse_result.encoding = encoding
+        parse_result.reference = uri_ref
+        parse_result.lazy_normalize = lazy_normalize
+        return parse_result
+
+    @classmethod
+    def from_parts(cls, scheme=None, userinfo=None, host=None, port=None,
+                   path=None, query=None, fragment=None, encoding='utf-8',
+                   lazy_normalize=True):
+        """Create a ParseResult instance from its parts."""
+        authority = ''
+        if userinfo is not None:
+            authority += userinfo + '@'
+        if host is not None:
+            authority += host
+        if port is not None:
+            authority += ':{0}'.format(int(port))
+        uri_ref = uri.URIReference(scheme=scheme,
+                                   authority=authority,
+                                   path=path,
+                                   query=query,
+                                   fragment=fragment,
+                                   encoding=encoding)
+        if not lazy_normalize:
+            uri_ref = uri_ref.normalize()
+        to_bytes = compat.to_bytes
+        userinfo, host, port = authority_from(uri_ref, strict=True)
+        return cls(scheme=to_bytes(scheme, encoding),
+                   userinfo=to_bytes(userinfo, encoding),
+                   host=to_bytes(host, encoding),
+                   port=port,
+                   path=to_bytes(path, encoding),
+                   query=to_bytes(query, encoding),
+                   fragment=to_bytes(fragment, encoding),
+                   uri_ref=uri_ref,
+                   encoding=encoding,
+                   lazy_normalize=lazy_normalize)
+
+    @classmethod
+    def from_string(cls, uri_string, encoding='utf-8', strict=True,
+                    lazy_normalize=True):
+        """Parse a URI 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
+        :param bool strict: Parse strictly according to :rfc:`3986` if True.
+            If False, parse similarly to the standard library's urlparse
+            function.
+        :returns: :class:`ParseResultBytes` or subclass thereof
+        """
+        reference = uri.URIReference.from_string(uri_string, encoding)
+        if not lazy_normalize:
+            reference = reference.normalize()
+        userinfo, host, port = authority_from(reference, strict)
+
+        to_bytes = compat.to_bytes
+        return cls(scheme=to_bytes(reference.scheme, encoding),
+                   userinfo=to_bytes(userinfo, encoding),
+                   host=to_bytes(host, encoding),
+                   port=port,
+                   path=to_bytes(reference.path, encoding),
+                   query=to_bytes(reference.query, encoding),
+                   fragment=to_bytes(reference.fragment, encoding),
+                   uri_ref=reference,
+                   encoding=encoding,
+                   lazy_normalize=lazy_normalize)
+
+    @property
+    def authority(self):
+        """Return the normalized authority."""
+        return self.reference.authority.encode(self.encoding)
+
+    def copy_with(self, scheme=misc.UseExisting, userinfo=misc.UseExisting,
+                  host=misc.UseExisting, port=misc.UseExisting,
+                  path=misc.UseExisting, query=misc.UseExisting,
+                  fragment=misc.UseExisting, lazy_normalize=True):
+        """Create a copy of this instance replacing with specified parts."""
+        attributes = zip(PARSED_COMPONENTS,
+                         (scheme, userinfo, host, port, path, query, fragment))
+        attrs_dict = {}
+        for name, value in attributes:
+            if value is misc.UseExisting:
+                value = getattr(self, name)
+            if not isinstance(value, bytes) and hasattr(value, 'encode'):
+                value = value.encode(self.encoding)
+            attrs_dict[name] = value
+        authority = self._generate_authority(attrs_dict)
+        to_str = compat.to_str
+        ref = self.reference.copy_with(
+            scheme=to_str(attrs_dict['scheme'], self.encoding),
+            authority=to_str(authority, self.encoding),
+            path=to_str(attrs_dict['path'], self.encoding),
+            query=to_str(attrs_dict['query'], self.encoding),
+            fragment=to_str(attrs_dict['fragment'], self.encoding)
+        )
+        if not lazy_normalize:
+            ref = ref.normalize()
+        return ParseResultBytes(
+            uri_ref=ref,
+            encoding=self.encoding,
+            lazy_normalize=lazy_normalize,
+            **attrs_dict
+        )
+
+    def unsplit(self, use_idna=False):
+        """Create a URI bytes object from the components.
+
+        :returns: The parsed URI reconstituted as a string.
+        :rtype: bytes
+        """
+        parse_result = self
+        if use_idna and self.host:
+            # self.host is bytes, to encode to idna, we need to decode it
+            # first
+            host = self.host.decode(self.encoding)
+            hostbytes = host.encode('idna')
+            parse_result = self.copy_with(host=hostbytes)
+        if self.lazy_normalize:
+            parse_result = parse_result.copy_with(lazy_normalize=False)
+        uri = parse_result.reference.unsplit()
+        return uri.encode(self.encoding)
+
+
+def split_authority(authority):
+    # Initialize our expected return values
+    userinfo = host = port = None
+    # Initialize an extra var we may need to use
+    extra_host = None
+    # Set-up rest in case there is no userinfo portion
+    rest = authority
+
+    if '@' in authority:
+        userinfo, rest = authority.rsplit('@', 1)
+
+    # Handle IPv6 host addresses
+    if rest.startswith('['):
+        host, rest = rest.split(']', 1)
+        host += ']'
+
+    if ':' in rest:
+        extra_host, port = rest.split(':', 1)
+    elif not host and rest:
+        host = rest
+
+    if extra_host and not host:
+        host = extra_host
+
+    return userinfo, host, port
+
+
+def authority_from(reference, strict):
+    try:
+        subauthority = reference.authority_info()
+    except exceptions.InvalidAuthority:
+        if strict:
+            raise
+        userinfo, host, port = split_authority(reference.authority)
+    else:
+        # Thanks to Richard Barrell for this idea:
+        # https://twitter.com/0x2ba22e11/status/617338811975139328
+        userinfo, host, port = (subauthority.get(p)
+                                for p in ('userinfo', 'host', 'port'))
+
+    if port:
+        try:
+            port = int(port)
+        except ValueError:
+            raise exceptions.InvalidPort(port)
+    return userinfo, host, port
diff --git a/src/pip/_vendor/urllib3/packages/rfc3986/uri.py b/src/pip/_vendor/urllib3/packages/rfc3986/uri.py
new file mode 100644
index 0000000..244fff5
--- /dev/null
+++ b/src/pip/_vendor/urllib3/packages/rfc3986/uri.py
@@ -0,0 +1,492 @@
+"""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
+import warnings
+
+from . import compat
+from . import exceptions as exc
+from . import misc
+from . import normalizers
+from . import validators
+
+
+class URIReference(namedtuple('URIReference', misc.URI_COMPONENTS)):
+    """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 adddres 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)
+
+    @classmethod
+    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,
+        )
+
+    def authority_info(self):
+        """Return a dictionary with the ``userinfo``, ``host``, and ``port``.
+
+        If the authority is not valid, it will raise a
+        :class:`~rfc3986.exceptions.InvalidAuthority` Exception.
+
+        :returns:
+            ``{'userinfo': 'username:password', 'host': 'www.example.com',
+            'port': '80'}``
+        :rtype: dict
+        :raises rfc3986.exceptions.InvalidAuthority:
+            If the authority is not ``None`` and can not be parsed.
+        """
+        if not self.authority:
+            return {'userinfo': None, 'host': None, 'port': None}
+
+        match = misc.SUBAUTHORITY_MATCHER.match(self.authority)
+
+        if match is None:
+            # In this case, we have an authority that was parsed from the URI
+            # Reference, but it cannot be further parsed by our
+            # misc.SUBAUTHORITY_MATCHER. In this case it must not be a valid
+            # authority.
+            raise exc.InvalidAuthority(self.authority.encode(self.encoding))
+
+        # We had a match, now let's ensure that it is actually a valid host
+        # address if it is IPv4
+        matches = match.groupdict()
+        host = matches.get('host')
+
+        if (host and misc.IPv4_MATCHER.match(host) and not
+                validators.valid_ipv4_host_address(host)):
+            # If we have a host, it appears to be IPv4 and it does not have
+            # valid bytes, it is an InvalidAuthority.
+            raise exc.InvalidAuthority(self.authority.encode(self.encoding))
+
+        return matches
+
+    @property
+    def host(self):
+        """If present, a string representing the host."""
+        try:
+            authority = self.authority_info()
+        except exc.InvalidAuthority:
+            return None
+        return authority['host']
+
+    @property
+    def port(self):
+        """If present, the port extracted from the authority."""
+        try:
+            authority = self.authority_info()
+        except exc.InvalidAuthority:
+            return None
+        return authority['port']
+
+    @property
+    def userinfo(self):
+        """If present, the userinfo extracted from the authority."""
+        try:
+            authority = self.authority_info()
+        except exc.InvalidAuthority:
+            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
+        """
+        return bool(misc.ABSOLUTE_URI_MATCHER.match(self.unsplit()))
+
+    def is_valid(self, **kwargs):
+        """Determine if the URI is valid.
+
+        .. deprecated:: 1.1.0
+
+            Use the :class:`~rfc3986.validators.Validator` object instead.
+
+        :param bool require_scheme: Set to ``True`` if you wish to require the
+            presence of the scheme component.
+        :param bool require_authority: Set to ``True`` if you wish to require
+            the presence of the authority component.
+        :param bool require_path: Set to ``True`` if you wish to require the
+            presence of the path component.
+        :param bool require_query: Set to ``True`` if you wish to require the
+            presence of the query component.
+        :param bool require_fragment: Set to ``True`` if you wish to require
+            the presence of the fragment component.
+        :returns: ``True`` if the URI is valid. ``False`` otherwise.
+        :rtype: bool
+        """
+        warnings.warn("Please use rfc3986.validators.Validator instead. "
+                      "This method will be eventually removed.",
+                      DeprecationWarning)
+        validators = [
+            (self.scheme_is_valid, kwargs.get('require_scheme', False)),
+            (self.authority_is_valid, kwargs.get('require_authority', False)),
+            (self.path_is_valid, kwargs.get('require_path', False)),
+            (self.query_is_valid, kwargs.get('require_query', False)),
+            (self.fragment_is_valid, kwargs.get('require_fragment', False)),
+            ]
+        return all(v(r) for v, r in validators)
+
+    def authority_is_valid(self, require=False):
+        """Determine if the authority component is valid.
+
+        .. deprecated:: 1.1.0
+
+            Use the :class:`~rfc3986.validators.Validator` object instead.
+
+        :param bool require:
+            Set to ``True`` to require the presence of this component.
+        :returns:
+            ``True`` if the authority is valid. ``False`` otherwise.
+        :rtype:
+            bool
+        """
+        warnings.warn("Please use rfc3986.validators.Validator instead. "
+                      "This method will be eventually removed.",
+                      DeprecationWarning)
+        try:
+            self.authority_info()
+        except exc.InvalidAuthority:
+            return False
+
+        return validators.authority_is_valid(
+            self.authority,
+            host=self.host,
+            require=require,
+        )
+
+    def scheme_is_valid(self, require=False):
+        """Determine if the scheme component is valid.
+
+        .. deprecated:: 1.1.0
+
+            Use the :class:`~rfc3986.validators.Validator` object instead.
+
+        :param str require: Set to ``True`` to require the presence of this
+            component.
+        :returns: ``True`` if the scheme is valid. ``False`` otherwise.
+        :rtype: bool
+        """
+        warnings.warn("Please use rfc3986.validators.Validator instead. "
+                      "This method will be eventually removed.",
+                      DeprecationWarning)
+        return validators.scheme_is_valid(self.scheme, require)
+
+    def path_is_valid(self, require=False):
+        """Determine if the path component is valid.
+
+        .. deprecated:: 1.1.0
+
+            Use the :class:`~rfc3986.validators.Validator` object instead.
+
+        :param str require: Set to ``True`` to require the presence of this
+            component.
+        :returns: ``True`` if the path is valid. ``False`` otherwise.
+        :rtype: bool
+        """
+        warnings.warn("Please use rfc3986.validators.Validator instead. "
+                      "This method will be eventually removed.",
+                      DeprecationWarning)
+        return validators.path_is_valid(self.path, require)
+
+    def query_is_valid(self, require=False):
+        """Determine if the query component is valid.
+
+        .. deprecated:: 1.1.0
+
+            Use the :class:`~rfc3986.validators.Validator` object instead.
+
+        :param str require: Set to ``True`` to require the presence of this
+            component.
+        :returns: ``True`` if the query is valid. ``False`` otherwise.
+        :rtype: bool
+        """
+        warnings.warn("Please use rfc3986.validators.Validator instead. "
+                      "This method will be eventually removed.",
+                      DeprecationWarning)
+        return validators.query_is_valid(self.query, require)
+
+    def fragment_is_valid(self, require=False):
+        """Determine if the fragment component is valid.
+
+        .. deprecated:: 1.1.0
+
+            Use the Validator object instead.
+
+        :param str require: Set to ``True`` to require the presence of this
+            component.
+        :returns: ``True`` if the fragment is valid. ``False`` otherwise.
+        :rtype: bool
+        """
+        warnings.warn("Please use rfc3986.validators.Validator instead. "
+                      "This method will be eventually removed.",
+                      DeprecationWarning)
+        return validators.fragment_is_valid(self.fragment, require)
+
+    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 normalized_equality(self, other_ref):
+        """Compare this URIReference to another URIReference.
+
+        :param URIReference other_ref: (required), The reference with which
+            we're comparing.
+        :returns: ``True`` if the references are equal, ``False`` otherwise.
+        :rtype: bool
+        """
+        return tuple(self.normalize()) == tuple(other_ref.normalize())
+
+    def resolve_with(self, base_uri, strict=False):
+        """Use an absolute URI Reference to resolve this relative reference.
+
+        Assuming this is a relative reference that you would like to resolve,
+        use the provided base URI to resolve it.
+
+        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 rfc3986.exceptions.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 exc.ResolutionError(base_uri)
+
+        # This is optional per
+        # http://tools.ietf.org/html/rfc3986#section-5.2.1
+        base_uri = base_uri.normalize()
+
+        # The reference we're resolving
+        resolving = self
+
+        if not strict and resolving.scheme == base_uri.scheme:
+            resolving = resolving.copy_with(scheme=None)
+
+        # http://tools.ietf.org/html/rfc3986#page-32
+        if resolving.scheme is not None:
+            target = resolving.copy_with(
+                path=normalizers.normalize_path(resolving.path)
+            )
+        else:
+            if resolving.authority is not None:
+                target = resolving.copy_with(
+                    scheme=base_uri.scheme,
+                    path=normalizers.normalize_path(resolving.path)
+                )
+            else:
+                if resolving.path is None:
+                    if resolving.query is not None:
+                        query = resolving.query
+                    else:
+                        query = base_uri.query
+                    target = resolving.copy_with(
+                        scheme=base_uri.scheme,
+                        authority=base_uri.authority,
+                        path=base_uri.path,
+                        query=query
+                    )
+                else:
+                    if resolving.path.startswith('/'):
+                        path = normalizers.normalize_path(resolving.path)
+                    else:
+                        path = normalizers.normalize_path(
+                            misc.merge_paths(base_uri, resolving.path)
+                        )
+                    target = resolving.copy_with(
+                        scheme=base_uri.scheme,
+                        authority=base_uri.authority,
+                        path=path,
+                        query=resolving.query
+                    )
+        return target
+
+    def unsplit(self):
+        """Create a URI string from the components.
+
+        :returns: The URI Reference reconstituted as a string.
+        :rtype: str
+        """
+        # See http://tools.ietf.org/html/rfc3986#section-5.3
+        result_list = []
+        if self.scheme:
+            result_list.extend([self.scheme, ':'])
+        if self.authority:
+            result_list.extend(['//', self.authority])
+        if self.path:
+            result_list.append(self.path)
+        if self.query is not None:
+            result_list.extend(['?', self.query])
+        if self.fragment is not None:
+            result_list.extend(['#', self.fragment])
+        return ''.join(result_list)
+
+    def copy_with(self, scheme=misc.UseExisting, authority=misc.UseExisting,
+                  path=misc.UseExisting, query=misc.UseExisting,
+                  fragment=misc.UseExisting):
+        """Create a copy of this reference with the new components.
+
+        :param str scheme:
+            (optional) The scheme to use for the new reference.
+        :param str authority:
+            (optional) The authority to use for the new reference.
+        :param str path:
+            (optional) The path to use for the new reference.
+        :param str query:
+            (optional) The query to use for the new reference.
+        :param str fragment:
+            (optional) The fragment to use for the new reference.
+        :returns:
+            New URIReference with provided components.
+        :rtype:
+            URIReference
+        """
+        attributes = {
+            'scheme': scheme,
+            'authority': authority,
+            'path': path,
+            'query': query,
+            'fragment': fragment,
+        }
+        for key, value in list(attributes.items()):
+            if value is misc.UseExisting:
+                del attributes[key]
+        uri = self._replace(**attributes)
+        uri.encoding = self.encoding
+        return uri
diff --git a/src/pip/_vendor/urllib3/packages/rfc3986/validators.py b/src/pip/_vendor/urllib3/packages/rfc3986/validators.py
new file mode 100644
index 0000000..c781325
--- /dev/null
+++ b/src/pip/_vendor/urllib3/packages/rfc3986/validators.py
@@ -0,0 +1,428 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017 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.
+"""Module containing the validation logic for rfc3986."""
+from . import exceptions
+from . import misc
+from . import normalizers
+
+
+class Validator(object):
+    """Object used to configure validation of all objects in rfc3986.
+
+    .. versionadded:: 1.0
+
+    Example usage::
+
+         >>> from rfc3986 import api, validators
+         >>> uri = api.uri_reference('https://github.com/')
+         >>> validator = validators.Validator().require_presence_of(
+         ...    'scheme', 'host', 'path',
+         ... ).allow_schemes(
+         ...    'http', 'https',
+         ... ).allow_hosts(
+         ...    '127.0.0.1', 'github.com',
+         ... )
+         >>> validator.validate(uri)
+         >>> invalid_uri = rfc3986.uri_reference('imap://mail.google.com')
+         >>> validator.validate(invalid_uri)
+         Traceback (most recent call last):
+         ...
+         rfc3986.exceptions.MissingComponentError: ('path was required but
+         missing', URIReference(scheme=u'imap', authority=u'mail.google.com',
+         path=None, query=None, fragment=None), ['path'])
+
+    """
+
+    COMPONENT_NAMES = frozenset([
+        'scheme',
+        'userinfo',
+        'host',
+        'port',
+        'path',
+        'query',
+        'fragment',
+    ])
+
+    def __init__(self):
+        """Initialize our default validations."""
+        self.allowed_schemes = set()
+        self.allowed_hosts = set()
+        self.allowed_ports = set()
+        self.allow_password = True
+        self.required_components = {
+            'scheme': False,
+            'userinfo': False,
+            'host': False,
+            'port': False,
+            'path': False,
+            'query': False,
+            'fragment': False,
+        }
+        self.validated_components = self.required_components.copy()
+
+    def allow_schemes(self, *schemes):
+        """Require the scheme to be one of the provided schemes.
+
+        .. versionadded:: 1.0
+
+        :param schemes:
+            Schemes, without ``://`` that are allowed.
+        :returns:
+            The validator instance.
+        :rtype:
+            Validator
+        """
+        for scheme in schemes:
+            self.allowed_schemes.add(normalizers.normalize_scheme(scheme))
+        return self
+
+    def allow_hosts(self, *hosts):
+        """Require the host to be one of the provided hosts.
+
+        .. versionadded:: 1.0
+
+        :param hosts:
+            Hosts that are allowed.
+        :returns:
+            The validator instance.
+        :rtype:
+            Validator
+        """
+        for host in hosts:
+            self.allowed_hosts.add(normalizers.normalize_host(host))
+        return self
+
+    def allow_ports(self, *ports):
+        """Require the port to be one of the provided ports.
+
+        .. versionadded:: 1.0
+
+        :param ports:
+            Ports that are allowed.
+        :returns:
+            The validator instance.
+        :rtype:
+            Validator
+        """
+        for port in ports:
+            port_int = int(port, base=10)
+            if 0 <= port_int <= 65535:
+                self.allowed_ports.add(port)
+        return self
+
+    def allow_use_of_password(self):
+        """Allow passwords to be present in the URI.
+
+        .. versionadded:: 1.0
+
+        :returns:
+            The validator instance.
+        :rtype:
+            Validator
+        """
+        self.allow_password = True
+        return self
+
+    def forbid_use_of_password(self):
+        """Prevent passwords from being included in the URI.
+
+        .. versionadded:: 1.0
+
+        :returns:
+            The validator instance.
+        :rtype:
+            Validator
+        """
+        self.allow_password = False
+        return self
+
+    def check_validity_of(self, *components):
+        """Check the validity of the components provided.
+
+        This can be specified repeatedly.
+
+        .. versionadded:: 1.1
+
+        :param components:
+            Names of components from :attr:`Validator.COMPONENT_NAMES`.
+        :returns:
+            The validator instance.
+        :rtype:
+            Validator
+        """
+        components = [c.lower() for c in components]
+        for component in components:
+            if component not in self.COMPONENT_NAMES:
+                raise ValueError(
+                    '"{}" is not a valid component'.format(component)
+                )
+        self.validated_components.update({
+            component: True for component in components
+        })
+        return self
+
+    def require_presence_of(self, *components):
+        """Require the components provided.
+
+        This can be specified repeatedly.
+
+        .. versionadded:: 1.0
+
+        :param components:
+            Names of components from :attr:`Validator.COMPONENT_NAMES`.
+        :returns:
+            The validator instance.
+        :rtype:
+            Validator
+        """
+        components = [c.lower() for c in components]
+        for component in components:
+            if component not in self.COMPONENT_NAMES:
+                raise ValueError(
+                    '"{}" is not a valid component'.format(component)
+                )
+        self.required_components.update({
+            component: True for component in components
+        })
+        return self
+
+    def validate(self, uri):
+        """Check a URI for conditions specified on this validator.
+
+        .. versionadded:: 1.0
+
+        :param uri:
+            Parsed URI to validate.
+        :type uri:
+            rfc3986.uri.URIReference
+        :raises MissingComponentError:
+            When a required component is missing.
+        :raises UnpermittedComponentError:
+            When a component is not one of those allowed.
+        :raises PasswordForbidden:
+            When a password is present in the userinfo component but is
+            not permitted by configuration.
+        :raises InvalidComponentsError:
+            When a component was found to be invalid.
+        """
+        if not self.allow_password:
+            check_password(uri)
+
+        required_components = [
+            component
+            for component, required in self.required_components.items()
+            if required
+        ]
+        validated_components = [
+            component
+            for component, required in self.validated_components.items()
+            if required
+        ]
+        if required_components:
+            ensure_required_components_exist(uri, required_components)
+        if validated_components:
+            ensure_components_are_valid(uri, validated_components)
+
+        ensure_one_of(self.allowed_schemes, uri, 'scheme')
+        ensure_one_of(self.allowed_hosts, uri, 'host')
+        ensure_one_of(self.allowed_ports, uri, 'port')
+
+
+def check_password(uri):
+    """Assert that there is no password present in the uri."""
+    userinfo = uri.userinfo
+    if not userinfo:
+        return
+    credentials = userinfo.split(':', 1)
+    if len(credentials) <= 1:
+        return
+    raise exceptions.PasswordForbidden(uri)
+
+
+def ensure_one_of(allowed_values, uri, attribute):
+    """Assert that the uri's attribute is one of the allowed values."""
+    value = getattr(uri, attribute)
+    if value is not None and allowed_values and value not in allowed_values:
+        raise exceptions.UnpermittedComponentError(
+            attribute, value, allowed_values,
+        )
+
+
+def ensure_required_components_exist(uri, required_components):
+    """Assert that all required components are present in the URI."""
+    missing_components = sorted([
+        component
+        for component in required_components
+        if getattr(uri, component) is None
+    ])
+    if missing_components:
+        raise exceptions.MissingComponentError(uri, *missing_components)
+
+
+def is_valid(value, matcher, require):
+    """Determine if a value is valid based on the provided matcher.
+
+    :param str value:
+        Value to validate.
+    :param matcher:
+        Compiled regular expression to use to validate the value.
+    :param require:
+        Whether or not the value is required.
+    """
+    if require:
+        return (value is not None
+                and matcher.match(value))
+
+    # require is False and value is not None
+    return value is None or matcher.match(value)
+
+
+def authority_is_valid(authority, host=None, require=False):
+    """Determine if the authority string is valid.
+
+    :param str authority:
+        The authority to validate.
+    :param str host:
+        (optional) The host portion of the authority to validate.
+    :param bool require:
+        (optional) Specify if authority must not be None.
+    :returns:
+        ``True`` if valid, ``False`` otherwise
+    :rtype:
+        bool
+    """
+    validated = is_valid(authority, misc.SUBAUTHORITY_MATCHER, require)
+    if validated and host is not None and misc.IPv4_MATCHER.match(host):
+        return valid_ipv4_host_address(host)
+    return validated
+
+
+def scheme_is_valid(scheme, require=False):
+    """Determine if the scheme is valid.
+
+    :param str scheme:
+        The scheme string to validate.
+    :param bool require:
+        (optional) Set to ``True`` to require the presence of a scheme.
+    :returns:
+        ``True`` if the scheme is valid. ``False`` otherwise.
+    :rtype:
+        bool
+    """
+    return is_valid(scheme, misc.SCHEME_MATCHER, require)
+
+
+def path_is_valid(path, require=False):
+    """Determine if the path component is valid.
+
+    :param str path:
+        The path string to validate.
+    :param bool require:
+        (optional) Set to ``True`` to require the presence of a path.
+    :returns:
+        ``True`` if the path is valid. ``False`` otherwise.
+    :rtype:
+        bool
+    """
+    return is_valid(path, misc.PATH_MATCHER, require)
+
+
+def query_is_valid(query, require=False):
+    """Determine if the query component is valid.
+
+    :param str query:
+        The query string to validate.
+    :param bool require:
+        (optional) Set to ``True`` to require the presence of a query.
+    :returns:
+        ``True`` if the query is valid. ``False`` otherwise.
+    :rtype:
+        bool
+    """
+    return is_valid(query, misc.QUERY_MATCHER, require)
+
+
+def fragment_is_valid(fragment, require=False):
+    """Determine if the fragment component is valid.
+
+    :param str fragment:
+        The fragment string to validate.
+    :param bool require:
+        (optional) Set to ``True`` to require the presence of a fragment.
+    :returns:
+        ``True`` if the fragment is valid. ``False`` otherwise.
+    :rtype:
+        bool
+    """
+    return is_valid(fragment, misc.FRAGMENT_MATCHER, require)
+
+
+def valid_ipv4_host_address(host):
+    """Determine if the given host is a valid IPv4 address."""
+    # If the host exists, and it might be IPv4, check each byte in the
+    # address.
+    return all([0 <= int(byte, base=10) <= 255 for byte in host.split('.')])
+
+
+_COMPONENT_VALIDATORS = {
+    'scheme': scheme_is_valid,
+    'path': path_is_valid,
+    'query': query_is_valid,
+    'fragment': fragment_is_valid,
+}
+
+_SUBAUTHORITY_VALIDATORS = set(['userinfo', 'host', 'port'])
+
+
+def subauthority_component_is_valid(uri, component):
+    """Determine if the userinfo, host, and port are valid."""
+    try:
+        subauthority_dict = uri.authority_info()
+    except exceptions.InvalidAuthority:
+        return False
+
+    # If we can parse the authority into sub-components and we're not
+    # validating the port, we can assume it's valid.
+    if component != 'port':
+        return True
+
+    try:
+        port = int(subauthority_dict['port'])
+    except TypeError:
+        # If the port wasn't provided it'll be None and int(None) raises a
+        # TypeError
+        return True
+
+    return (0 <= port <= 65535)
+
+
+def ensure_components_are_valid(uri, validated_components):
+    """Assert that all components are valid in the URI."""
+    invalid_components = set([])
+    for component in validated_components:
+        if component in _SUBAUTHORITY_VALIDATORS:
+            if not subauthority_component_is_valid(uri, component):
+                invalid_components.add(component)
+            # Python's peephole optimizer means that while this continue *is*
+            # actually executed, coverage.py cannot detect that. See also,
+            # https://bitbucket.org/ned/coveragepy/issues/198/continue-marked-as-not-covered
+            continue  # nocov: Python 2.7, 3.3, 3.4
+
+        validator = _COMPONENT_VALIDATORS[component]
+        if not validator(getattr(uri, component)):
+            invalid_components.add(component)
+
+    if invalid_components:
+        raise exceptions.InvalidComponentsError(uri, *invalid_components)
diff --git a/src/pip/_vendor/urllib3/util/ssl_.py b/src/pip/_vendor/urllib3/util/ssl_.py
index d96e893..44f765e 100644
--- a/src/pip/_vendor/urllib3/util/ssl_.py
+++ b/src/pip/_vendor/urllib3/util/ssl_.py
@@ -2,13 +2,14 @@ from __future__ import absolute_import
 import errno
 import warnings
 import hmac
-import socket
+import re
 
 from binascii import hexlify, unhexlify
 from hashlib import md5, sha1, sha256
 
 from ..exceptions import SSLError, InsecurePlatformWarning, SNIMissingWarning
 from ..packages import six
+from ..packages.rfc3986 import abnf_regexp
 
 
 SSLContext = None
@@ -40,6 +41,16 @@ def _const_compare_digest_backport(a, b):
 _const_compare_digest = getattr(hmac, 'compare_digest',
                                 _const_compare_digest_backport)
 
+# Borrow rfc3986's regular expressions for IPv4
+# and IPv6 addresses for use in is_ipaddress()
+_IP_ADDRESS_REGEX = re.compile(
+    r'^(?:%s|%s|%s|%s)$' % (
+        abnf_regexp.IPv4_RE,
+        abnf_regexp.IPv6_RE,
+        abnf_regexp.IPv6_ADDRZ_RE,
+        abnf_regexp.IPv_FUTURE_RE
+    )
+)
 
 try:  # Test for SSL features
     import ssl
@@ -56,25 +67,6 @@ except ImportError:
     OP_NO_COMPRESSION = 0x20000
 
 
-# Python 2.7 doesn't have inet_pton on non-Linux so we fallback on inet_aton in
-# those cases. This means that we can only detect IPv4 addresses in this case.
-if hasattr(socket, 'inet_pton'):
-    inet_pton = socket.inet_pton
-else:
-    # Maybe we can use ipaddress if the user has urllib3[secure]?
-    try:
-        from pip._vendor import ipaddress
-
-        def inet_pton(_, host):
-            if isinstance(host, bytes):
-                host = host.decode('ascii')
-            return ipaddress.ip_address(host)
-
-    except ImportError:  # Platform-specific: Non-Linux
-        def inet_pton(_, host):
-            return socket.inet_aton(host)
-
-
 # A secure default.
 # Sources for more information on TLS ciphers:
 #
@@ -370,15 +362,4 @@ def is_ipaddress(hostname):
         # IDN A-label bytes are ASCII compatible.
         hostname = hostname.decode('ascii')
 
-    families = [socket.AF_INET]
-    if hasattr(socket, 'AF_INET6'):
-        families.append(socket.AF_INET6)
-
-    for af in families:
-        try:
-            inet_pton(af, hostname)
-        except (socket.error, ValueError, OSError):
-            pass
-        else:
-            return True
-    return False
+    return _IP_ADDRESS_REGEX.match(hostname) is not None
diff --git a/src/pip/_vendor/urllib3/util/url.py b/src/pip/_vendor/urllib3/util/url.py
index 6b6f996..7f70361 100644
--- a/src/pip/_vendor/urllib3/util/url.py
+++ b/src/pip/_vendor/urllib3/util/url.py
@@ -1,7 +1,10 @@
 from __future__ import absolute_import
+import re
 from collections import namedtuple
 
 from ..exceptions import LocationParseError
+from ..packages import six, rfc3986
+from ..packages.rfc3986.exceptions import RFC3986Exception
 
 
 url_attrs = ['scheme', 'auth', 'host', 'port', 'path', 'query', 'fragment']
@@ -10,6 +13,9 @@ url_attrs = ['scheme', 'auth', 'host', 'port', 'path', 'query', 'fragment']
 # urllib3 infers URLs without a scheme (None) to be http.
 NORMALIZABLE_SCHEMES = ('http', 'https', None)
 
+# Regex for detecting URLs with schemes. RFC 3986 Section 3.1
+SCHEME_REGEX = re.compile(r"^[a-zA-Z][a-zA-Z0-9+\-.]*://")
+
 
 class Url(namedtuple('Url', url_attrs)):
     """
@@ -98,6 +104,8 @@ class Url(namedtuple('Url', url_attrs)):
 
 def split_first(s, delims):
     """
+    Deprecated. No longer used by parse_url().
+
     Given a string and an iterable of delimiters, split on the first found
     delimiter. Return two split parts and the matched delimiter.
 
@@ -133,6 +141,9 @@ def parse_url(url):
     """
     Given a url, return a parsed :class:`.Url` namedtuple. Best-effort is
     performed to parse incomplete urls. Fields not provided will be None.
+    This parser is RFC 3986 compliant.
+
+    :param str url: URL to parse into a :class:`.Url` namedtuple.
 
     Partly backwards-compatible with :mod:`urlparse`.
 
@@ -145,81 +156,55 @@ def parse_url(url):
         >>> parse_url('/foo?bar')
         Url(scheme=None, host=None, port=None, path='/foo', query='bar', ...)
     """
-
-    # While this code has overlap with stdlib's urlparse, it is much
-    # simplified for our needs and less annoying.
-    # Additionally, this implementations does silly things to be optimal
-    # on CPython.
-
     if not url:
         # Empty
         return Url()
 
-    scheme = None
-    auth = None
-    host = None
-    port = None
-    path = None
-    fragment = None
-    query = None
-
-    # Scheme
-    if '://' in url:
-        scheme, url = url.split('://', 1)
-
-    # Find the earliest Authority Terminator
-    # (http://tools.ietf.org/html/rfc3986#section-3.2)
-    url, path_, delim = split_first(url, ['/', '?', '#'])
-
-    if delim:
-        # Reassemble the path
-        path = delim + path_
-
-    # Auth
-    if '@' in url:
-        # Last '@' denotes end of auth part
-        auth, url = url.rsplit('@', 1)
-
-    # IPv6
-    if url and url[0] == '[':
-        host, url = url.split(']', 1)
-        host += ']'
-
-    # Port
-    if ':' in url:
-        _host, port = url.split(':', 1)
-
-        if not host:
-            host = _host
-
-        if port:
-            # If given, ports must be integers. No whitespace, no plus or
-            # minus prefixes, no non-integer digits such as ^2 (superscript).
-            if not port.isdigit():
-                raise LocationParseError(url)
-            try:
-                port = int(port)
-            except ValueError:
-                raise LocationParseError(url)
-        else:
-            # Blank ports are cool, too. (rfc3986#section-3.2.3)
-            port = None
-
-    elif not host and url:
-        host = url
-
+    # RFC 3986 doesn't like URLs that have a host but don't start
+    # with a scheme and we support URLs like that so we need to
+    # detect that problem and add an empty scheme indication.
+    # We don't get hurt on path-only URLs here as it's stripped
+    # off and given an empty scheme anyways.
+    if not SCHEME_REGEX.search(url):
+        url = "//" + url
+
+    try:
+        parse_result = rfc3986.urlparse(url, encoding="utf-8")
+    except (ValueError, RFC3986Exception):
+        raise LocationParseError(url)
+
+    # RFC 3986 doesn't assert ports must be non-negative.
+    if parse_result.port and parse_result.port < 0:
+        raise LocationParseError(url)
+
+    # For the sake of backwards compatibility we put empty
+    # string values for path if there are any defined values
+    # beyond the path in the URL.
+    # TODO: Remove this when we break backwards compatibility.
+    path = parse_result.path
     if not path:
-        return Url(scheme, auth, host, port, path, query, fragment)
-
-    # Fragment
-    if '#' in path:
-        path, fragment = path.split('#', 1)
-
-    # Query
-    if '?' in path:
-        path, query = path.split('?', 1)
-
-    return Url(scheme, auth, host, port, path, query, fragment)
+        if (parse_result.query is not None
+                or parse_result.fragment is not None):
+            path = ""
+        else:
+            path = None
+
+    # Ensure that each part of the URL is a `str` for
+    # backwards compatbility.
+    def to_str(x):
+        if six.PY2 and isinstance(x, six.string_types):
+            return x.encode('utf-8')
+        return x
+
+    return Url(
+        scheme=to_str(parse_result.scheme),
+        auth=to_str(parse_result.userinfo),
+        host=to_str(parse_result.hostname),
+        port=parse_result.port,
+        path=to_str(path),
+        query=to_str(parse_result.query),
+        fragment=to_str(parse_result.fragment)
+    )
 
 
 def get_host(url):
-- 
2.24.1