summaryrefslogtreecommitdiff
path: root/pip
diff options
context:
space:
mode:
authorDonald Stufft <donald@stufft.io>2016-05-10 20:15:25 -0400
committerDonald Stufft <donald@stufft.io>2016-05-10 20:15:25 -0400
commitdb3112ad98797bef1156af97d4f8d9e0144d7361 (patch)
tree90a89a9d8473685095917f2b3b731c00632a45b5 /pip
parentaab40c24e55fdf633f98229c90fc582469e9d98e (diff)
downloadpip-db3112ad98797bef1156af97d4f8d9e0144d7361.tar.gz
Upgrade bundled dependencies (#3664)
* We actually have distlib 0.2.3 vendored * Update colorama to 0.3.7 * Use unix line endings * Upgrade requests to 2.10.0 * Upgrade pyparsing to 2.1.1 * Update pkg_resources to 21.0.0
Diffstat (limited to 'pip')
-rw-r--r--pip/_vendor/README.rst2
-rw-r--r--pip/_vendor/colorama/__init__.py2
-rw-r--r--pip/_vendor/colorama/ansitowin32.py10
-rw-r--r--pip/_vendor/colorama/initialise.py3
-rw-r--r--pip/_vendor/pkg_resources/__init__.py6
-rw-r--r--pip/_vendor/pyparsing.py76
-rw-r--r--pip/_vendor/requests/__init__.py16
-rw-r--r--pip/_vendor/requests/adapters.py52
-rw-r--r--pip/_vendor/requests/api.py6
-rw-r--r--pip/_vendor/requests/auth.py19
-rw-r--r--pip/_vendor/requests/cookies.py6
-rw-r--r--pip/_vendor/requests/models.py10
-rw-r--r--pip/_vendor/requests/packages/urllib3/__init__.py11
-rw-r--r--pip/_vendor/requests/packages/urllib3/_collections.py2
-rw-r--r--pip/_vendor/requests/packages/urllib3/connection.py64
-rw-r--r--pip/_vendor/requests/packages/urllib3/connectionpool.py93
-rw-r--r--pip/_vendor/requests/packages/urllib3/contrib/appengine.py12
-rw-r--r--pip/_vendor/requests/packages/urllib3/contrib/ntlmpool.py20
-rw-r--r--pip/_vendor/requests/packages/urllib3/contrib/pyopenssl.py64
-rw-r--r--pip/_vendor/requests/packages/urllib3/contrib/socks.py172
-rw-r--r--pip/_vendor/requests/packages/urllib3/exceptions.py8
-rw-r--r--pip/_vendor/requests/packages/urllib3/fields.py4
-rw-r--r--pip/_vendor/requests/packages/urllib3/poolmanager.py17
-rw-r--r--pip/_vendor/requests/packages/urllib3/response.py38
-rw-r--r--pip/_vendor/requests/packages/urllib3/util/__init__.py2
-rw-r--r--pip/_vendor/requests/packages/urllib3/util/response.py2
-rw-r--r--pip/_vendor/requests/packages/urllib3/util/retry.py14
-rw-r--r--pip/_vendor/requests/packages/urllib3/util/ssl_.py11
-rw-r--r--pip/_vendor/requests/sessions.py65
-rw-r--r--pip/_vendor/requests/status_codes.py1
-rw-r--r--pip/_vendor/requests/structures.py4
-rw-r--r--pip/_vendor/requests/utils.py39
-rw-r--r--pip/_vendor/vendor.txt24
33 files changed, 655 insertions, 220 deletions
diff --git a/pip/_vendor/README.rst b/pip/_vendor/README.rst
index 3a3f4d91f..a9cddb114 100644
--- a/pip/_vendor/README.rst
+++ b/pip/_vendor/README.rst
@@ -95,7 +95,7 @@ such as OS packages.
pkg_resources
-------------
-pkg_resources has been pulled in from setuptools 20.7.0
+pkg_resources has been pulled in from setuptools 21.0.0
Modifications
diff --git a/pip/_vendor/colorama/__init__.py b/pip/_vendor/colorama/__init__.py
index 8fc3f0113..670e6b397 100644
--- a/pip/_vendor/colorama/__init__.py
+++ b/pip/_vendor/colorama/__init__.py
@@ -3,5 +3,5 @@ from .initialise import init, deinit, reinit, colorama_text
from .ansi import Fore, Back, Style, Cursor
from .ansitowin32 import AnsiToWin32
-__version__ = '0.3.6'
+__version__ = '0.3.7'
diff --git a/pip/_vendor/colorama/ansitowin32.py b/pip/_vendor/colorama/ansitowin32.py
index a750d2ab0..b7ff6f213 100644
--- a/pip/_vendor/colorama/ansitowin32.py
+++ b/pip/_vendor/colorama/ansitowin32.py
@@ -13,6 +13,10 @@ if windll is not None:
winterm = WinTerm()
+def is_stream_closed(stream):
+ return not hasattr(stream, 'closed') or stream.closed
+
+
def is_a_tty(stream):
return hasattr(stream, 'isatty') and stream.isatty()
@@ -64,12 +68,12 @@ class AnsiToWin32(object):
# should we strip ANSI sequences from our output?
if strip is None:
- strip = conversion_supported or (not wrapped.closed and not is_a_tty(wrapped))
+ strip = conversion_supported or (not is_stream_closed(wrapped) and not is_a_tty(wrapped))
self.strip = strip
# should we should convert ANSI sequences into win32 calls?
if convert is None:
- convert = conversion_supported and not wrapped.closed and is_a_tty(wrapped)
+ convert = conversion_supported and not is_stream_closed(wrapped) and is_a_tty(wrapped)
self.convert = convert
# dict of ansi codes to win32 functions and parameters
@@ -145,7 +149,7 @@ class AnsiToWin32(object):
def reset_all(self):
if self.convert:
self.call_win32('m', (0,))
- elif not self.strip and not self.wrapped.closed:
+ elif not self.strip and not is_stream_closed(self.wrapped):
self.wrapped.write(Style.RESET_ALL)
diff --git a/pip/_vendor/colorama/initialise.py b/pip/_vendor/colorama/initialise.py
index 4bce9f229..834962a35 100644
--- a/pip/_vendor/colorama/initialise.py
+++ b/pip/_vendor/colorama/initialise.py
@@ -16,7 +16,8 @@ atexit_done = False
def reset_all():
- AnsiToWin32(orig_stdout).reset_all()
+ if AnsiToWin32 is not None: # Issue #74: objects might become None at exit
+ AnsiToWin32(orig_stdout).reset_all()
def init(autoreset=False, convert=None, strip=None, wrap=True):
diff --git a/pip/_vendor/pkg_resources/__init__.py b/pip/_vendor/pkg_resources/__init__.py
index bbceaac76..91e1a9d24 100644
--- a/pip/_vendor/pkg_resources/__init__.py
+++ b/pip/_vendor/pkg_resources/__init__.py
@@ -986,11 +986,11 @@ class _ReqExtras(dict):
Return False if the req has a marker and fails
evaluation. Otherwise, return True.
"""
- evals = (
+ extra_evals = (
req.marker.evaluate({'extra': extra})
- for extra in self.get(req) or ['']
+ for extra in self.get(req, ()) + (None,)
)
- return not req.marker or any(evals)
+ return not req.marker or any(extra_evals)
class Environment(object):
diff --git a/pip/_vendor/pyparsing.py b/pip/_vendor/pyparsing.py
index 39c2b8275..56f196637 100644
--- a/pip/_vendor/pyparsing.py
+++ b/pip/_vendor/pyparsing.py
@@ -57,8 +57,8 @@ The pyparsing module handles some of the problems that are typically vexing when
- embedded comments
"""
-__version__ = "2.1.0"
-__versionTime__ = "7 Feb 2016 14:09"
+__version__ = "2.1.1"
+__versionTime__ = "21 Mar 2016 05:04 UTC"
__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>"
import string
@@ -328,7 +328,7 @@ class ParseResults(object):
if isinstance(v,_ParseResultsWithOffset):
self.__tokdict[k] = self.__tokdict.get(k,list()) + [v]
sub = v[0]
- elif isinstance(k,int):
+ elif isinstance(k,(int,slice)):
self.__toklist[k] = v
sub = v
else:
@@ -541,7 +541,17 @@ class ParseResults(object):
item_fn = self.items
else:
item_fn = self.iteritems
- return dict((k,v.asDict()) if isinstance(v, ParseResults) else (k,v) for k,v in item_fn())
+
+ def toItem(obj):
+ if isinstance(obj, ParseResults):
+ if obj.haskeys():
+ return obj.asDict()
+ else:
+ return [toItem(v) for v in obj]
+ else:
+ return obj
+
+ return dict((k,toItem(v)) for k,v in item_fn())
def copy( self ):
"""Returns a new copy of a C{ParseResults} object."""
@@ -1552,7 +1562,7 @@ class ParserElement(object):
def __eq__(self,other):
if isinstance(other, ParserElement):
- return self is other or self.__dict__ == other.__dict__
+ return self is other or vars(self) == vars(other)
elif isinstance(other, basestring):
try:
self.parseString(_ustr(other), parseAll=True)
@@ -1931,15 +1941,15 @@ class Regex(Token):
class QuotedString(Token):
"""Token for matching strings that are delimited by quoting characters.
"""
- def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None):
- """
- Defined with the following parameters:
+ def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None, convertWhitespaceEscapes=True):
+ r"""Defined with the following parameters:
- quoteChar - string of one or more characters defining the quote delimiting string
- escChar - character to escape quotes, typically backslash (default=None)
- escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=None)
- multiline - boolean indicating whether quotes can span multiple lines (default=C{False})
- unquoteResults - boolean indicating whether the matched text should be unquoted (default=C{True})
- endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=C{None} => same as quoteChar)
+ - convertWhitespaceEscapes - convert escaped whitespace (C{'\t'}, C{'\n'}, etc.) to actual whitespace (default=C{True})
"""
super(QuotedString,self).__init__()
@@ -1965,6 +1975,7 @@ class QuotedString(Token):
self.escChar = escChar
self.escQuote = escQuote
self.unquoteResults = unquoteResults
+ self.convertWhitespaceEscapes = convertWhitespaceEscapes
if multiline:
self.flags = re.MULTILINE | re.DOTALL
@@ -2018,6 +2029,17 @@ class QuotedString(Token):
ret = ret[self.quoteCharLen:-self.endQuoteCharLen]
if isinstance(ret,basestring):
+ # replace escaped whitespace
+ if '\\' in ret and self.convertWhitespaceEscapes:
+ ws_map = {
+ r'\t' : '\t',
+ r'\n' : '\n',
+ r'\f' : '\f',
+ r'\r' : '\r',
+ }
+ for wslit,wschar in ws_map.items():
+ ret = ret.replace(wslit, wschar)
+
# replace escaped characters
if self.escChar:
ret = re.sub(self.escCharReplacePattern,"\g<1>",ret)
@@ -2622,14 +2644,16 @@ class Each(ParseExpression):
tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired
failed = []
for e in tmpExprs:
- if e.canParseNext(instring, tmpLoc):
+ try:
+ tmpLoc = e.tryParse( instring, tmpLoc )
+ except ParseException:
+ failed.append(e)
+ else:
matchOrder.append(self.opt1map.get(id(e),e))
if e in tmpReqd:
tmpReqd.remove(e)
elif e in tmpOpt:
tmpOpt.remove(e)
- else:
- failed.append(e)
if len(failed) == len(tmpExprs):
keepMatching = False
@@ -2938,7 +2962,7 @@ class SkipTo(ParseElementEnhance):
self.mayIndexError = False
self.includeMatch = include
self.asList = False
- if failOn is not None and isinstance(failOn, basestring):
+ if isinstance(failOn, basestring):
self.failOn = Literal(failOn)
else:
self.failOn = failOn
@@ -2956,7 +2980,7 @@ class SkipTo(ParseElementEnhance):
while tmploc <= instrlen:
if self_failOn_canParseNext is not None:
# break if failOn expression matches
- if self_failOn.canParseNext(instring, tmploc):
+ if self_failOn_canParseNext(instring, tmploc):
break
if self_ignoreExpr_tryParse is not None:
@@ -3400,10 +3424,7 @@ def originalTextFor(expr, asString=True):
extractText = lambda s,l,t: s[t._original_start:t._original_end]
else:
def extractText(s,l,t):
- del t[:]
- t.insert(0, s[t._original_start:t._original_end])
- del t["_original_start"]
- del t["_original_end"]
+ t[:] = [s[t.pop('_original_start'):t.pop('_original_end')]]
matchExpr.setParseAction(extractText)
return matchExpr
@@ -3476,10 +3497,7 @@ def replaceWith(replStr):
"""Helper method for common parse actions that simply return a literal value. Especially
useful when used with C{L{transformString<ParserElement.transformString>}()}.
"""
- #def _replFunc(*args):
- # return [replStr]
- #return _replFunc
- return functools.partial(next, itertools.repeat([replStr]))
+ return lambda s,l,t: [replStr]
def removeQuotes(s,l,t):
"""Helper parse action for removing quotation marks from parsed quoted strings.
@@ -3496,22 +3514,6 @@ def downcaseTokens(s,l,t):
"""Helper parse action to convert tokens to lower case."""
return [ tt.lower() for tt in map(_ustr,t) ]
-def getTokensEndLoc():
- """Method to be called from within a parse action to determine the end
- location of the parsed tokens."""
- import inspect
- fstack = inspect.stack()
- try:
- # search up the stack (through intervening argument normalizers) for correct calling routine
- for f in fstack[2:]:
- if f[3] == "_parseNoCache":
- endloc = f[0].f_locals["loc"]
- return endloc
- else:
- raise ParseFatalException("incorrect usage of getTokensEndLoc - may only be called from within a parse action")
- finally:
- del fstack
-
def _makeTags(tagStr, xml):
"""Internal helper to construct opening and closing tag expressions, given a tag name"""
if isinstance(tagStr,basestring):
diff --git a/pip/_vendor/requests/__init__.py b/pip/_vendor/requests/__init__.py
index bd5b5b974..82c0f7807 100644
--- a/pip/_vendor/requests/__init__.py
+++ b/pip/_vendor/requests/__init__.py
@@ -36,17 +36,17 @@ usage:
The other HTTP methods are supported - see `requests.api`. Full documentation
is at <http://python-requests.org>.
-:copyright: (c) 2015 by Kenneth Reitz.
+:copyright: (c) 2016 by Kenneth Reitz.
:license: Apache 2.0, see LICENSE for more details.
"""
__title__ = 'requests'
-__version__ = '2.9.1'
-__build__ = 0x020901
+__version__ = '2.10.0'
+__build__ = 0x021000
__author__ = 'Kenneth Reitz'
__license__ = 'Apache 2.0'
-__copyright__ = 'Copyright 2015 Kenneth Reitz'
+__copyright__ = 'Copyright 2016 Kenneth Reitz'
# Attempt to enable urllib3's SNI support, if possible
try:
@@ -55,6 +55,12 @@ try:
except ImportError:
pass
+import warnings
+
+# urllib3's DependencyWarnings should be silenced.
+from .packages.urllib3.exceptions import DependencyWarning
+warnings.simplefilter('ignore', DependencyWarning)
+
from . import utils
from .models import Request, Response, PreparedRequest
from .api import request, get, head, post, patch, put, delete, options
@@ -63,7 +69,7 @@ from .status_codes import codes
from .exceptions import (
RequestException, Timeout, URLRequired,
TooManyRedirects, HTTPError, ConnectionError,
- FileModeWarning,
+ FileModeWarning, ConnectTimeout, ReadTimeout
)
# Set default logging handler to avoid "No handler found" warnings.
diff --git a/pip/_vendor/requests/adapters.py b/pip/_vendor/requests/adapters.py
index 6266d5be3..23e448f42 100644
--- a/pip/_vendor/requests/adapters.py
+++ b/pip/_vendor/requests/adapters.py
@@ -19,7 +19,7 @@ from .packages.urllib3.util.retry import Retry
from .compat import urlparse, basestring
from .utils import (DEFAULT_CA_BUNDLE_PATH, get_encoding_from_headers,
prepend_scheme_if_needed, get_auth_from_url, urldefragauth,
- select_proxy)
+ select_proxy, to_native_string)
from .structures import CaseInsensitiveDict
from .packages.urllib3.exceptions import ClosedPoolError
from .packages.urllib3.exceptions import ConnectTimeoutError
@@ -33,9 +33,15 @@ from .packages.urllib3.exceptions import SSLError as _SSLError
from .packages.urllib3.exceptions import ResponseError
from .cookies import extract_cookies_to_jar
from .exceptions import (ConnectionError, ConnectTimeout, ReadTimeout, SSLError,
- ProxyError, RetryError)
+ ProxyError, RetryError, InvalidSchema)
from .auth import _basic_auth_str
+try:
+ from .packages.urllib3.contrib.socks import SOCKSProxyManager
+except ImportError:
+ def SOCKSProxyManager(*args, **kwargs):
+ raise InvalidSchema("Missing dependencies for SOCKS support.")
+
DEFAULT_POOLBLOCK = False
DEFAULT_POOLSIZE = 10
DEFAULT_RETRIES = 0
@@ -65,7 +71,7 @@ class HTTPAdapter(BaseAdapter):
:param pool_connections: The number of urllib3 connection pools to cache.
:param pool_maxsize: The maximum number of connections to save in the pool.
- :param int max_retries: The maximum number of retries each connection
+ :param max_retries: The maximum number of retries each connection
should attempt. Note, this applies only to failed DNS lookups, socket
connections and connection timeouts, never to requests where data has
made it to the server. By default, Requests does not retry failed
@@ -149,9 +155,22 @@ class HTTPAdapter(BaseAdapter):
:param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager.
:returns: ProxyManager
"""
- if not proxy in self.proxy_manager:
+ if proxy in self.proxy_manager:
+ manager = self.proxy_manager[proxy]
+ elif proxy.lower().startswith('socks'):
+ username, password = get_auth_from_url(proxy)
+ manager = self.proxy_manager[proxy] = SOCKSProxyManager(
+ proxy,
+ username=username,
+ password=password,
+ num_pools=self._pool_connections,
+ maxsize=self._pool_maxsize,
+ block=self._pool_block,
+ **proxy_kwargs
+ )
+ else:
proxy_headers = self.proxy_headers(proxy)
- self.proxy_manager[proxy] = proxy_from_url(
+ manager = self.proxy_manager[proxy] = proxy_from_url(
proxy,
proxy_headers=proxy_headers,
num_pools=self._pool_connections,
@@ -159,7 +178,7 @@ class HTTPAdapter(BaseAdapter):
block=self._pool_block,
**proxy_kwargs)
- return self.proxy_manager[proxy]
+ return manager
def cert_verify(self, conn, url, verify, cert):
"""Verify a SSL certificate. This method should not be called from user
@@ -264,10 +283,12 @@ class HTTPAdapter(BaseAdapter):
def close(self):
"""Disposes of any internal state.
- Currently, this just closes the PoolManager, which closes pooled
- connections.
+ Currently, this closes the PoolManager and any active ProxyManager,
+ which closes any pooled connections.
"""
self.poolmanager.clear()
+ for proxy in self.proxy_manager.values():
+ proxy.clear()
def request_url(self, request, proxies):
"""Obtain the url to use when making the final request.
@@ -284,10 +305,16 @@ class HTTPAdapter(BaseAdapter):
"""
proxy = select_proxy(request.url, proxies)
scheme = urlparse(request.url).scheme
- if proxy and scheme != 'https':
+
+ is_proxied_http_request = (proxy and scheme != 'https')
+ using_socks_proxy = False
+ if proxy:
+ proxy_scheme = urlparse(proxy).scheme.lower()
+ using_socks_proxy = proxy_scheme.startswith('socks')
+
+ url = request.path_url
+ if is_proxied_http_request and not using_socks_proxy:
url = urldefragauth(request.url)
- else:
- url = request.path_url
return url
@@ -434,6 +461,9 @@ class HTTPAdapter(BaseAdapter):
if isinstance(e.reason, ResponseError):
raise RetryError(e, request=request)
+ if isinstance(e.reason, _ProxyError):
+ raise ProxyError(e, request=request)
+
raise ConnectionError(e, request=request)
except ClosedPoolError as e:
diff --git a/pip/_vendor/requests/api.py b/pip/_vendor/requests/api.py
index b21a1a4fa..c2068d0ed 100644
--- a/pip/_vendor/requests/api.py
+++ b/pip/_vendor/requests/api.py
@@ -24,7 +24,11 @@ def request(method, url, **kwargs):
:param json: (optional) json data to send in the body of the :class:`Request`.
:param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
:param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
- :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': ('filename', fileobj)}``) for multipart encoding upload.
+ :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.
+ ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')``
+ or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string
+ defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers
+ to add for the file.
:param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
:param timeout: (optional) How long to wait for the server to send data
before giving up, as a float, or a :ref:`(connect timeout, read
diff --git a/pip/_vendor/requests/auth.py b/pip/_vendor/requests/auth.py
index 2af55fb5e..73f8e9da8 100644
--- a/pip/_vendor/requests/auth.py
+++ b/pip/_vendor/requests/auth.py
@@ -47,6 +47,15 @@ class HTTPBasicAuth(AuthBase):
self.username = username
self.password = password
+ def __eq__(self, other):
+ return all([
+ self.username == getattr(other, 'username', None),
+ self.password == getattr(other, 'password', None)
+ ])
+
+ def __ne__(self, other):
+ return not self == other
+
def __call__(self, r):
r.headers['Authorization'] = _basic_auth_str(self.username, self.password)
return r
@@ -84,6 +93,7 @@ class HTTPDigestAuth(AuthBase):
qop = self._thread_local.chal.get('qop')
algorithm = self._thread_local.chal.get('algorithm')
opaque = self._thread_local.chal.get('opaque')
+ hash_utf8 = None
if algorithm is None:
_algorithm = 'MD5'
@@ -221,3 +231,12 @@ class HTTPDigestAuth(AuthBase):
self._thread_local.num_401_calls = 1
return r
+
+ def __eq__(self, other):
+ return all([
+ self.username == getattr(other, 'username', None),
+ self.password == getattr(other, 'password', None)
+ ])
+
+ def __ne__(self, other):
+ return not self == other
diff --git a/pip/_vendor/requests/cookies.py b/pip/_vendor/requests/cookies.py
index b85fd2b62..eee5168f2 100644
--- a/pip/_vendor/requests/cookies.py
+++ b/pip/_vendor/requests/cookies.py
@@ -277,6 +277,12 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
dictionary[cookie.name] = cookie.value
return dictionary
+ def __contains__(self, name):
+ try:
+ return super(RequestsCookieJar, self).__contains__(name)
+ except CookieConflictError:
+ return True
+
def __getitem__(self, name):
"""Dict-like __getitem__() for compatibility with client code. Throws
exception if there are more than one cookie with name. In that case,
diff --git a/pip/_vendor/requests/models.py b/pip/_vendor/requests/models.py
index 4bcbc5484..fe4bec1bd 100644
--- a/pip/_vendor/requests/models.py
+++ b/pip/_vendor/requests/models.py
@@ -103,8 +103,10 @@ class RequestEncodingMixin(object):
"""Build the body for a multipart/form-data request.
Will successfully encode files when passed as a dict or a list of
- 2-tuples. Order is retained if data is a list of 2-tuples but arbitrary
+ tuples. Order is retained if data is a list of tuples but arbitrary
if parameters are supplied as a dict.
+ The tuples may be 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype)
+ or 4-tuples (filename, fileobj, contentype, custom_headers).
"""
if (not files):
@@ -463,9 +465,11 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
def prepare_content_length(self, body):
if hasattr(body, 'seek') and hasattr(body, 'tell'):
+ curr_pos = body.tell()
body.seek(0, 2)
- self.headers['Content-Length'] = builtin_str(body.tell())
- body.seek(0, 0)
+ end_pos = body.tell()
+ self.headers['Content-Length'] = builtin_str(max(0, end_pos - curr_pos))
+ body.seek(curr_pos, 0)
elif body is not None:
l = super_len(body)
if l:
diff --git a/pip/_vendor/requests/packages/urllib3/__init__.py b/pip/_vendor/requests/packages/urllib3/__init__.py
index e43991a97..73668991f 100644
--- a/pip/_vendor/requests/packages/urllib3/__init__.py
+++ b/pip/_vendor/requests/packages/urllib3/__init__.py
@@ -32,7 +32,7 @@ except ImportError:
__author__ = 'Andrey Petrov (andrey.petrov@shazow.net)'
__license__ = 'MIT'
-__version__ = '1.13.1'
+__version__ = '1.15.1'
__all__ = (
'HTTPConnectionPool',
@@ -68,22 +68,25 @@ def add_stderr_logger(level=logging.DEBUG):
handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(message)s'))
logger.addHandler(handler)
logger.setLevel(level)
- logger.debug('Added a stderr logging handler to logger: %s' % __name__)
+ logger.debug('Added a stderr logging handler to logger: %s', __name__)
return handler
# ... Clean up.
del NullHandler
+# All warning filters *must* be appended unless you're really certain that they
+# shouldn't be: otherwise, it's very hard for users to use most Python
+# mechanisms to silence them.
# SecurityWarning's always go off by default.
warnings.simplefilter('always', exceptions.SecurityWarning, append=True)
# SubjectAltNameWarning's should go off once per host
-warnings.simplefilter('default', exceptions.SubjectAltNameWarning)
+warnings.simplefilter('default', exceptions.SubjectAltNameWarning, append=True)
# InsecurePlatformWarning's don't vary between requests, so we keep it default.
warnings.simplefilter('default', exceptions.InsecurePlatformWarning,
append=True)
# SNIMissingWarnings should go off only once.
-warnings.simplefilter('default', exceptions.SNIMissingWarning)
+warnings.simplefilter('default', exceptions.SNIMissingWarning, append=True)
def disable_warnings(category=exceptions.HTTPWarning):
diff --git a/pip/_vendor/requests/packages/urllib3/_collections.py b/pip/_vendor/requests/packages/urllib3/_collections.py
index 67f3ce994..77cee0170 100644
--- a/pip/_vendor/requests/packages/urllib3/_collections.py
+++ b/pip/_vendor/requests/packages/urllib3/_collections.py
@@ -134,7 +134,7 @@ class HTTPHeaderDict(MutableMapping):
def __init__(self, headers=None, **kwargs):
super(HTTPHeaderDict, self).__init__()
- self._container = {}
+ self._container = OrderedDict()
if headers is not None:
if isinstance(headers, HTTPHeaderDict):
self._copy_from(headers)
diff --git a/pip/_vendor/requests/packages/urllib3/connection.py b/pip/_vendor/requests/packages/urllib3/connection.py
index 1e4cd4175..5ce008048 100644
--- a/pip/_vendor/requests/packages/urllib3/connection.py
+++ b/pip/_vendor/requests/packages/urllib3/connection.py
@@ -1,5 +1,6 @@
from __future__ import absolute_import
import datetime
+import logging
import os
import sys
import socket
@@ -38,7 +39,7 @@ from .exceptions import (
SubjectAltNameWarning,
SystemTimeWarning,
)
-from .packages.ssl_match_hostname import match_hostname
+from .packages.ssl_match_hostname import match_hostname, CertificateError
from .util.ssl_ import (
resolve_cert_reqs,
@@ -50,6 +51,10 @@ from .util.ssl_ import (
from .util import connection
+from ._collections import HTTPHeaderDict
+
+log = logging.getLogger(__name__)
+
port_by_scheme = {
'http': 80,
'https': 443,
@@ -162,6 +167,38 @@ class HTTPConnection(_HTTPConnection, object):
conn = self._new_conn()
self._prepare_conn(conn)
+ def request_chunked(self, method, url, body=None, headers=None):
+ """
+ Alternative to the common request method, which sends the
+ body with chunked encoding and not as one block
+ """
+ headers = HTTPHeaderDict(headers if headers is not None else {})
+ skip_accept_encoding = 'accept-encoding' in headers
+ self.putrequest(method, url, skip_accept_encoding=skip_accept_encoding)
+ for header, value in headers.items():
+ self.putheader(header, value)
+ if 'transfer-encoding' not in headers:
+ self.putheader('Transfer-Encoding', 'chunked')
+ self.endheaders()
+
+ if body is not None:
+ stringish_types = six.string_types + (six.binary_type,)
+ if isinstance(body, stringish_types):
+ body = (body,)
+ for chunk in body:
+ if not chunk:
+ continue
+ if not isinstance(chunk, six.binary_type):
+ chunk = chunk.encode('utf8')
+ len_str = hex(len(chunk))[2:]
+ self.send(len_str.encode('utf-8'))
+ self.send(b'\r\n')
+ self.send(chunk)
+ self.send(b'\r\n')
+
+ # After the if clause, to always have a closed body
+ self.send(b'0\r\n\r\n')
+
class HTTPSConnection(HTTPConnection):
default_port = port_by_scheme['https']
@@ -265,21 +302,26 @@ class VerifiedHTTPSConnection(HTTPSConnection):
'for details.)'.format(hostname)),
SubjectAltNameWarning
)
-
- # In case the hostname is an IPv6 address, strip the square
- # brackets from it before using it to validate. This is because
- # a certificate with an IPv6 address in it won't have square
- # brackets around that address. Sadly, match_hostname won't do this
- # for us: it expects the plain host part without any extra work
- # that might have been done to make it palatable to httplib.
- asserted_hostname = self.assert_hostname or hostname
- asserted_hostname = asserted_hostname.strip('[]')
- match_hostname(cert, asserted_hostname)
+ _match_hostname(cert, self.assert_hostname or hostname)
self.is_verified = (resolved_cert_reqs == ssl.CERT_REQUIRED or
self.assert_fingerprint is not None)
+def _match_hostname(cert, asserted_hostname):
+ try:
+ match_hostname(cert, asserted_hostname)
+ except CertificateError as e:
+ log.error(
+ 'Certificate did not match expected hostname: %s. '
+ 'Certificate: %s', asserted_hostname, cert
+ )
+ # Add cert to exception and reraise so client code can inspect
+ # the cert when catching the exception, if they want to
+ e._peer_cert = cert
+ raise
+
+
if ssl:
# Make a copy for testing.
UnverifiedHTTPSConnection = HTTPSConnection
diff --git a/pip/_vendor/requests/packages/urllib3/connectionpool.py b/pip/_vendor/requests/packages/urllib3/connectionpool.py
index 995b4167b..3fcfb1201 100644
--- a/pip/_vendor/requests/packages/urllib3/connectionpool.py
+++ b/pip/_vendor/requests/packages/urllib3/connectionpool.py
@@ -69,7 +69,13 @@ class ConnectionPool(object):
if not host:
raise LocationValueError("No host specified.")
- self.host = host
+ # httplib doesn't like it when we include brackets in ipv6 addresses
+ # Specifically, if we include brackets but also pass the port then
+ # httplib crazily doubles up the square brackets on the Host header.
+ # Instead, we need to make sure we never pass ``None`` as the port.
+ # However, for backward compatibility reasons we can't actually
+ # *assert* that.
+ self.host = host.strip('[]')
self.port = port
def __str__(self):
@@ -203,8 +209,8 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
Return a fresh :class:`HTTPConnection`.
"""
self.num_connections += 1
- log.info("Starting new HTTP connection (%d): %s" %
- (self.num_connections, self.host))
+ log.info("Starting new HTTP connection (%d): %s",
+ self.num_connections, self.host)
conn = self.ConnectionCls(host=self.host, port=self.port,
timeout=self.timeout.connect_timeout,
@@ -239,7 +245,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
# If this is a persistent connection, check if it got disconnected
if conn and is_connection_dropped(conn):
- log.info("Resetting dropped connection: %s" % self.host)
+ log.info("Resetting dropped connection: %s", self.host)
conn.close()
if getattr(conn, 'auto_open', 1) == 0:
# This is a proxied connection that has been mutated by
@@ -272,7 +278,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
except Full:
# This should never happen if self.block == True
log.warning(
- "Connection pool is full, discarding connection: %s" %
+ "Connection pool is full, discarding connection: %s",
self.host)
# Connection never got put back into the pool, close it.
@@ -318,7 +324,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
if 'timed out' in str(err) or 'did not complete (read)' in str(err): # Python 2.6
raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value)
- def _make_request(self, conn, method, url, timeout=_Default,
+ def _make_request(self, conn, method, url, timeout=_Default, chunked=False,
**httplib_request_kw):
"""
Perform a request on a given urllib connection object taken from our
@@ -350,7 +356,10 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
# conn.request() calls httplib.*.request, not the method in
# urllib3.request. It also calls makefile (recv) on the socket.
- conn.request(method, url, **httplib_request_kw)
+ if chunked:
+ conn.request_chunked(method, url, **httplib_request_kw)
+ else:
+ conn.request(method, url, **httplib_request_kw)
# Reset the timeout for the recv() on the socket
read_timeout = timeout_obj.read_timeout
@@ -382,9 +391,8 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
# AppEngine doesn't have a version attr.
http_version = getattr(conn, '_http_vsn_str', 'HTTP/?')
- log.debug("\"%s %s %s\" %s %s" % (method, url, http_version,
- httplib_response.status,
- httplib_response.length))
+ log.debug("\"%s %s %s\" %s %s", method, url, http_version,
+ httplib_response.status, httplib_response.length)
try:
assert_header_parsing(httplib_response.msg)
@@ -435,7 +443,8 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
def urlopen(self, method, url, body=None, headers=None, retries=None,
redirect=True, assert_same_host=True, timeout=_Default,
- pool_timeout=None, release_conn=None, **response_kw):
+ pool_timeout=None, release_conn=None, chunked=False,
+ **response_kw):
"""
Get a connection from the pool and perform an HTTP request. This is the
lowest level call for making a request, so you'll need to specify all
@@ -512,6 +521,11 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
back into the pool. If None, it takes the value of
``response_kw.get('preload_content', True)``.
+ :param chunked:
+ If True, urllib3 will send the body using chunked transfer
+ encoding. Otherwise, urllib3 will send the body using the standard
+ content-length form. Defaults to False.
+
:param \**response_kw:
Additional parameters are passed to
:meth:`urllib3.response.HTTPResponse.from_httplib`
@@ -542,6 +556,10 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
# complains about UnboundLocalError.
err = None
+ # Keep track of whether we cleanly exited the except block. This
+ # ensures we do proper cleanup in finally.
+ clean_exit = False
+
try:
# Request a connection from the queue.
timeout_obj = self._get_timeout(timeout)
@@ -556,13 +574,14 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
# Make the request on the httplib connection object.
httplib_response = self._make_request(conn, method, url,
timeout=timeout_obj,
- body=body, headers=headers)
+ body=body, headers=headers,
+ chunked=chunked)
# If we're going to release the connection in ``finally:``, then
- # the request doesn't need to know about the connection. Otherwise
+ # the response doesn't need to know about the connection. Otherwise
# it will also try to release it and we'll have a double-release
# mess.
- response_conn = not release_conn and conn
+ response_conn = conn if not release_conn else None
# Import httplib's response into our own wrapper object
response = HTTPResponse.from_httplib(httplib_response,
@@ -570,10 +589,8 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
connection=response_conn,
**response_kw)
- # else:
- # The connection will be put back into the pool when
- # ``response.release_conn()`` is called (implicitly by
- # ``response.read()``)
+ # Everything went great!
+ clean_exit = True
except Empty:
# Timed out by queue.
@@ -583,22 +600,19 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
# Close the connection. If a connection is reused on which there
# was a Certificate error, the next request will certainly raise
# another Certificate error.
- conn = conn and conn.close()
- release_conn = True
+ clean_exit = False
raise SSLError(e)
except SSLError:
# Treat SSLError separately from BaseSSLError to preserve
# traceback.
- conn = conn and conn.close()
- release_conn = True
+ clean_exit = False
raise
except (TimeoutError, HTTPException, SocketError, ProtocolError) as e:
# Discard the connection for these exceptions. It will be
# be replaced during the next _get_conn() call.
- conn = conn and conn.close()
- release_conn = True
+ clean_exit = False
if isinstance(e, (SocketError, NewConnectionError)) and self.proxy:
e = ProxyError('Cannot connect to proxy.', e)
@@ -613,6 +627,14 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
err = e
finally:
+ if not clean_exit:
+ # We hit some kind of exception, handled or otherwise. We need
+ # to throw the connection away unless explicitly told not to.
+ # Close the connection, set the variable to None, and make sure
+ # we put the None back in the pool to avoid leaking it.
+ conn = conn and conn.close()
+ release_conn = True
+
if release_conn:
# Put the connection back to be reused. If the connection is
# expired then it will be None, which will get replaced with a
@@ -622,7 +644,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
if not conn:
# Try again
log.warning("Retrying (%r) after connection "
- "broken by '%r': %s" % (retries, err, url))
+ "broken by '%r': %s", retries, err, url)
return self.urlopen(method, url, body, headers, retries,
redirect, assert_same_host,
timeout=timeout, pool_timeout=pool_timeout,
@@ -644,7 +666,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
raise
return response
- log.info("Redirecting %s -> %s" % (url, redirect_location))
+ log.info("Redirecting %s -> %s", url, redirect_location)
return self.urlopen(
method, redirect_location, body, headers,
retries=retries, redirect=redirect,
@@ -654,9 +676,17 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
# Check if we should retry the HTTP response.
if retries.is_forced_retry(method, status_code=response.status):
- retries = retries.increment(method, url, response=response, _pool=self)
+ try:
+ retries = retries.increment(method, url, response=response, _pool=self)
+ except MaxRetryError:
+ if retries.raise_on_status:
+ # Release the connection for this response, since we're not
+ # returning it to be released manually.
+ response.release_conn()
+ raise
+ return response
retries.sleep()
- log.info("Forced retry: %s" % url)
+ log.info("Forced retry: %s", url)
return self.urlopen(
method, url, body, headers,
retries=retries, redirect=redirect,
@@ -742,7 +772,7 @@ class HTTPSConnectionPool(HTTPConnectionPool):
except AttributeError: # Platform-specific: Python 2.6
set_tunnel = conn._set_tunnel
- if sys.version_info <= (2, 6, 4) and not self.proxy_headers: # Python 2.6.4 and older
+ if sys.version_info <= (2, 6, 4) and not self.proxy_headers: # Python 2.6.4 and older
set_tunnel(self.host, self.port)
else:
set_tunnel(self.host, self.port, self.proxy_headers)
@@ -754,8 +784,8 @@ class HTTPSConnectionPool(HTTPConnectionPool):
Return a fresh :class:`httplib.HTTPSConnection`.
"""
self.num_connections += 1
- log.info("Starting new HTTPS connection (%d): %s"
- % (self.num_connections, self.host))
+ log.info("Starting new HTTPS connection (%d): %s",
+ self.num_connections, self.host)
if not self.ConnectionCls or self.ConnectionCls is DummyConnection:
raise SSLError("Can't connect to HTTPS URL because the SSL "
@@ -812,6 +842,7 @@ def connection_from_url(url, **kw):
>>> r = conn.request('GET', '/')
"""
scheme, host, port = get_host(url)
+ port = port or port_by_scheme.get(scheme, 80)
if scheme == 'https':
return HTTPSConnectionPool(host, port=port, **kw)
else:
diff --git a/pip/_vendor/requests/packages/urllib3/contrib/appengine.py b/pip/_vendor/requests/packages/urllib3/contrib/appengine.py
index 884cdb220..f4289c0ff 100644
--- a/pip/_vendor/requests/packages/urllib3/contrib/appengine.py
+++ b/pip/_vendor/requests/packages/urllib3/contrib/appengine.py
@@ -144,7 +144,7 @@ class AppEngineManager(RequestMethods):
if retries.is_forced_retry(method, status_code=http_response.status):
retries = retries.increment(
method, url, response=http_response, _pool=self)
- log.info("Forced retry: %s" % url)
+ log.info("Forced retry: %s", url)
retries.sleep()
return self.urlopen(
method, url,
@@ -164,6 +164,14 @@ class AppEngineManager(RequestMethods):
if content_encoding == 'deflate':
del urlfetch_resp.headers['content-encoding']
+ transfer_encoding = urlfetch_resp.headers.get('transfer-encoding')
+ # We have a full response's content,
+ # so let's make sure we don't report ourselves as chunked data.
+ if transfer_encoding == 'chunked':
+ encodings = transfer_encoding.split(",")
+ encodings.remove('chunked')
+ urlfetch_resp.headers['transfer-encoding'] = ','.join(encodings)
+
return HTTPResponse(
# In order for decoding to work, we must present the content as
# a file-like object.
@@ -177,7 +185,7 @@ class AppEngineManager(RequestMethods):
if timeout is Timeout.DEFAULT_TIMEOUT:
return 5 # 5s is the default timeout for URLFetch.
if isinstance(timeout, Timeout):
- if timeout.read is not timeout.connect:
+ if timeout._read is not timeout._connect:
warnings.warn(
"URLFetch does not support granular timeout settings, "
"reverting to total timeout.", AppEnginePlatformWarning)
diff --git a/pip/_vendor/requests/packages/urllib3/contrib/ntlmpool.py b/pip/_vendor/requests/packages/urllib3/contrib/ntlmpool.py
index c136a238d..11d0b5c34 100644
--- a/pip/_vendor/requests/packages/urllib3/contrib/ntlmpool.py
+++ b/pip/_vendor/requests/packages/urllib3/contrib/ntlmpool.py
@@ -43,8 +43,8 @@ class NTLMConnectionPool(HTTPSConnectionPool):
# Performs the NTLM handshake that secures the connection. The socket
# must be kept open while requests are performed.
self.num_connections += 1
- log.debug('Starting NTLM HTTPS connection no. %d: https://%s%s' %
- (self.num_connections, self.host, self.authurl))
+ log.debug('Starting NTLM HTTPS connection no. %d: https://%s%s',
+ self.num_connections, self.host, self.authurl)
headers = {}
headers['Connection'] = 'Keep-Alive'
@@ -56,13 +56,13 @@ class NTLMConnectionPool(HTTPSConnectionPool):
# Send negotiation message
headers[req_header] = (
'NTLM %s' % ntlm.create_NTLM_NEGOTIATE_MESSAGE(self.rawuser))
- log.debug('Request headers: %s' % headers)
+ log.debug('Request headers: %s', headers)
conn.request('GET', self.authurl, None, headers)
res = conn.getresponse()
reshdr = dict(res.getheaders())
- log.debug('Response status: %s %s' % (res.status, res.reason))
- log.debug('Response headers: %s' % reshdr)
- log.debug('Response data: %s [...]' % res.read(100))
+ log.debug('Response status: %s %s', res.status, res.reason)
+ log.debug('Response headers: %s', reshdr)
+ log.debug('Response data: %s [...]', res.read(100))
# Remove the reference to the socket, so that it can not be closed by
# the response object (we want to keep the socket open)
@@ -87,12 +87,12 @@ class NTLMConnectionPool(HTTPSConnectionPool):
self.pw,
NegotiateFlags)
headers[req_header] = 'NTLM %s' % auth_msg
- log.debug('Request headers: %s' % headers)
+ log.debug('Request headers: %s', headers)
conn.request('GET', self.authurl, None, headers)
res = conn.getresponse()
- log.debug('Response status: %s %s' % (res.status, res.reason))
- log.debug('Response headers: %s' % dict(res.getheaders()))
- log.debug('Response data: %s [...]' % res.read()[:100])
+ log.debug('Response status: %s %s', res.status, res.reason)
+ log.debug('Response headers: %s', dict(res.getheaders()))
+ log.debug('Response data: %s [...]', res.read()[:100])
if res.status != 200:
if res.status == 401:
raise Exception('Server rejected request: wrong '
diff --git a/pip/_vendor/requests/packages/urllib3/contrib/pyopenssl.py b/pip/_vendor/requests/packages/urllib3/contrib/pyopenssl.py
index 5996153af..ed3b9cc34 100644
--- a/pip/_vendor/requests/packages/urllib3/contrib/pyopenssl.py
+++ b/pip/_vendor/requests/packages/urllib3/contrib/pyopenssl.py
@@ -54,9 +54,17 @@ except SyntaxError as e:
import OpenSSL.SSL
from pyasn1.codec.der import decoder as der_decoder
from pyasn1.type import univ, constraint
-from socket import _fileobject, timeout, error as SocketError
+from socket import timeout, error as SocketError
+
+try: # Platform-specific: Python 2
+ from socket import _fileobject
+except ImportError: # Platform-specific: Python 3
+ _fileobject = None
+ from urllib3.packages.backports.makefile import backport_makefile
+
import ssl
import select
+import six
from .. import connection
from .. import util
@@ -90,7 +98,7 @@ _openssl_verify = {
OpenSSL.SSL.VERIFY_PEER + OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
}
-DEFAULT_SSL_CIPHER_LIST = util.ssl_.DEFAULT_CIPHERS
+DEFAULT_SSL_CIPHER_LIST = util.ssl_.DEFAULT_CIPHERS.encode('ascii')
# OpenSSL will only write 16K at a time
SSL_WRITE_BLOCKSIZE = 16384
@@ -104,6 +112,7 @@ def inject_into_urllib3():
connection.ssl_wrap_socket = ssl_wrap_socket
util.HAS_SNI = HAS_SNI
+ util.IS_PYOPENSSL = True
def extract_from_urllib3():
@@ -111,6 +120,7 @@ def extract_from_urllib3():
connection.ssl_wrap_socket = orig_connection_ssl_wrap_socket
util.HAS_SNI = orig_util_HAS_SNI
+ util.IS_PYOPENSSL = False
# Note: This is a slightly bug-fixed version of same from ndg-httpsclient.
@@ -135,7 +145,7 @@ def get_subj_alt_name(peer_cert):
for i in range(peer_cert.get_extension_count()):
ext = peer_cert.get_extension(i)
ext_name = ext.get_short_name()
- if ext_name != 'subjectAltName':
+ if ext_name != b'subjectAltName':
continue
# PyOpenSSL returns extension data in ASN.1 encoded form
@@ -167,13 +177,17 @@ class WrappedSocket(object):
self.socket = socket
self.suppress_ragged_eofs = suppress_ragged_eofs
self._makefile_refs = 0
+ self._closed = False
def fileno(self):
return self.socket.fileno()
- def makefile(self, mode, bufsize=-1):
- self._makefile_refs += 1
- return _fileobject(self, mode, bufsize, close=True)
+ # Copy-pasted from Python 3.5 source code
+ def _decref_socketios(self):
+ if self._makefile_refs > 0:
+ self._makefile_refs -= 1
+ if self._closed:
+ self.close()
def recv(self, *args, **kwargs):
try:
@@ -182,7 +196,7 @@ class WrappedSocket(object):
if self.suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'):
return b''
else:
- raise SocketError(e)
+ raise SocketError(str(e))
except OpenSSL.SSL.ZeroReturnError as e:
if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN:
return b''
@@ -198,6 +212,27 @@ class WrappedSocket(object):
else:
return data
+ def recv_into(self, *args, **kwargs):
+ try:
+ return self.connection.recv_into(*args, **kwargs)
+ except OpenSSL.SSL.SysCallError as e:
+ if self.suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'):
+ return 0
+ else:
+ raise SocketError(str(e))
+ except OpenSSL.SSL.ZeroReturnError as e:
+ if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN:
+ return 0
+ else:
+ raise
+ except OpenSSL.SSL.WantReadError:
+ rd, wd, ed = select.select(
+ [self.socket], [], [], self.socket.gettimeout())
+ if not rd:
+ raise timeout('The read operation timed out')
+ else:
+ return self.recv_into(*args, **kwargs)
+
def settimeout(self, timeout):
return self.socket.settimeout(timeout)
@@ -225,6 +260,7 @@ class WrappedSocket(object):
def close(self):
if self._makefile_refs < 1:
try:
+ self._closed = True
return self.connection.close()
except OpenSSL.SSL.Error:
return
@@ -262,6 +298,16 @@ class WrappedSocket(object):
self._makefile_refs -= 1
+if _fileobject: # Platform-specific: Python 2
+ def makefile(self, mode, bufsize=-1):
+ self._makefile_refs += 1
+ return _fileobject(self, mode, bufsize, close=True)
+else: # Platform-specific: Python 3
+ makefile = backport_makefile
+
+WrappedSocket.makefile = makefile
+
+
def _verify_callback(cnx, x509, err_no, err_depth, return_code):
return err_no == 0
@@ -285,7 +331,7 @@ def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
else:
ctx.set_default_verify_paths()
- # Disable TLS compression to migitate CRIME attack (issue #309)
+ # Disable TLS compression to mitigate CRIME attack (issue #309)
OP_NO_COMPRESSION = 0x20000
ctx.set_options(OP_NO_COMPRESSION)
@@ -293,6 +339,8 @@ def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
ctx.set_cipher_list(DEFAULT_SSL_CIPHER_LIST)
cnx = OpenSSL.SSL.Connection(ctx, sock)
+ if isinstance(server_hostname, six.text_type): # Platform-specific: Python 3
+ server_hostname = server_hostname.encode('utf-8')
cnx.set_tlsext_host_name(server_hostname)
cnx.set_connect_state()
while True:
diff --git a/pip/_vendor/requests/packages/urllib3/contrib/socks.py b/pip/_vendor/requests/packages/urllib3/contrib/socks.py
new file mode 100644
index 000000000..3748fee53
--- /dev/null
+++ b/pip/_vendor/requests/packages/urllib3/contrib/socks.py
@@ -0,0 +1,172 @@
+# -*- coding: utf-8 -*-
+"""
+SOCKS support for urllib3
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This contrib module contains provisional support for SOCKS proxies from within
+urllib3. This module supports SOCKS4 (specifically the SOCKS4A variant) and
+SOCKS5. To enable its functionality, either install PySocks or install this
+module with the ``socks`` extra.
+
+Known Limitations:
+
+- Currently PySocks does not support contacting remote websites via literal
+ IPv6 addresses. Any such connection attempt will fail.
+- Currently PySocks does not support IPv6 connections to the SOCKS proxy. Any
+ such connection attempt will fail.
+"""
+from __future__ import absolute_import
+
+try:
+ import socks
+except ImportError:
+ import warnings
+ from ..exceptions import DependencyWarning
+
+ warnings.warn((
+ 'SOCKS support in urllib3 requires the installation of optional '
+ 'dependencies: specifically, PySocks. For more information, see '
+ 'https://urllib3.readthedocs.org/en/latest/contrib.html#socks-proxies'
+ ),
+ DependencyWarning
+ )
+ raise
+
+from socket import error as SocketError, timeout as SocketTimeout
+
+from ..connection import (
+ HTTPConnection, HTTPSConnection
+)
+from ..connectionpool import (
+ HTTPConnectionPool, HTTPSConnectionPool
+)
+from ..exceptions import ConnectTimeoutError, NewConnectionError
+from ..poolmanager import PoolManager
+from ..util.url import parse_url
+
+try:
+ import ssl
+except ImportError:
+ ssl = None
+
+
+class SOCKSConnection(HTTPConnection):
+ """
+ A plain-text HTTP connection that connects via a SOCKS proxy.
+ """
+ def __init__(self, *args, **kwargs):
+ self._socks_options = kwargs.pop('_socks_options')
+ super(SOCKSConnection, self).__init__(*args, **kwargs)
+
+ def _new_conn(self):
+ """
+ Establish a new connection via the SOCKS proxy.
+ """
+ extra_kw = {}
+ if self.source_address:
+ extra_kw['source_address'] = self.source_address
+
+ if self.socket_options:
+ extra_kw['socket_options'] = self.socket_options
+
+ try:
+ conn = socks.create_connection(
+ (self.host, self.port),
+ proxy_type=self._socks_options['socks_version'],
+ proxy_addr=self._socks_options['proxy_host'],
+ proxy_port=self._socks_options['proxy_port'],
+ proxy_username=self._socks_options['username'],
+ proxy_password=self._socks_options['password'],
+ timeout=self.timeout,
+ **extra_kw
+ )
+
+ except SocketTimeout as e:
+ raise ConnectTimeoutError(
+ self, "Connection to %s timed out. (connect timeout=%s)" %
+ (self.host, self.timeout))
+
+ except socks.ProxyError as e:
+ # This is fragile as hell, but it seems to be the only way to raise
+ # useful errors here.
+ if e.socket_err:
+ error = e.socket_err
+ if isinstance(error, SocketTimeout):
+ raise ConnectTimeoutError(
+ self,
+ "Connection to %s timed out. (connect timeout=%s)" %
+ (self.host, self.timeout)
+ )
+ else:
+ raise NewConnectionError(
+ self,
+ "Failed to establish a new connection: %s" % error
+ )
+ else:
+ raise NewConnectionError(
+ self,
+ "Failed to establish a new connection: %s" % e
+ )
+
+ except SocketError as e: # Defensive: PySocks should catch all these.
+ raise NewConnectionError(
+ self, "Failed to establish a new connection: %s" % e)
+
+ return conn
+
+
+# We don't need to duplicate the Verified/Unverified distinction from
+# urllib3/connection.py here because the HTTPSConnection will already have been
+# correctly set to either the Verified or Unverified form by that module. This
+# means the SOCKSHTTPSConnection will automatically be the correct type.
+class SOCKSHTTPSConnection(SOCKSConnection, HTTPSConnection):
+ pass
+
+
+class SOCKSHTTPConnectionPool(HTTPConnectionPool):
+ ConnectionCls = SOCKSConnection
+
+
+class SOCKSHTTPSConnectionPool(HTTPSConnectionPool):
+ ConnectionCls = SOCKSHTTPSConnection
+
+
+class SOCKSProxyManager(PoolManager):
+ """
+ A version of the urllib3 ProxyManager that routes connections via the
+ defined SOCKS proxy.
+ """
+ pool_classes_by_scheme = {
+ 'http': SOCKSHTTPConnectionPool,
+ 'https': SOCKSHTTPSConnectionPool,
+ }
+
+ def __init__(self, proxy_url, username=None, password=None,
+ num_pools=10, headers=None, **connection_pool_kw):
+ parsed = parse_url(proxy_url)
+
+ if parsed.scheme == 'socks5':
+ socks_version = socks.PROXY_TYPE_SOCKS5
+ elif parsed.scheme == 'socks4':
+ socks_version = socks.PROXY_TYPE_SOCKS4
+ else:
+ raise ValueError(
+ "Unable to determine SOCKS version from %s" % proxy_url
+ )
+
+ self.proxy_url = proxy_url
+
+ socks_options = {
+ 'socks_version': socks_version,
+ 'proxy_host': parsed.host,
+ 'proxy_port': parsed.port,
+ 'username': username,
+ 'password': password,
+ }
+ connection_pool_kw['_socks_options'] = socks_options
+
+ super(SOCKSProxyManager, self).__init__(
+ num_pools, headers, **connection_pool_kw
+ )
+
+ self.pool_classes_by_scheme = SOCKSProxyManager.pool_classes_by_scheme
diff --git a/pip/_vendor/requests/packages/urllib3/exceptions.py b/pip/_vendor/requests/packages/urllib3/exceptions.py
index 8e07eb619..f2e65917b 100644
--- a/pip/_vendor/requests/packages/urllib3/exceptions.py
+++ b/pip/_vendor/requests/packages/urllib3/exceptions.py
@@ -180,6 +180,14 @@ class SNIMissingWarning(HTTPWarning):
pass
+class DependencyWarning(HTTPWarning):
+ """
+ Warned when an attempt is made to import a module with missing optional
+ dependencies.
+ """
+ pass
+
+
class ResponseNotChunked(ProtocolError, ValueError):
"Response needs to be chunked in order to read it as chunks."
pass
diff --git a/pip/_vendor/requests/packages/urllib3/fields.py b/pip/_vendor/requests/packages/urllib3/fields.py
index c7d48113b..8fa2a1276 100644
--- a/pip/_vendor/requests/packages/urllib3/fields.py
+++ b/pip/_vendor/requests/packages/urllib3/fields.py
@@ -36,11 +36,11 @@ def format_header_param(name, value):
result = '%s="%s"' % (name, value)
try:
result.encode('ascii')
- except UnicodeEncodeError:
+ except (UnicodeEncodeError, UnicodeDecodeError):
pass
else:
return result
- if not six.PY3: # Python 2:
+ if not six.PY3 and isinstance(value, six.text_type): # Python 2:
value = value.encode('utf-8')
value = email.utils.encode_rfc2231(value, 'utf-8')
value = '%s*=%s' % (name, value)
diff --git a/pip/_vendor/requests/packages/urllib3/poolmanager.py b/pip/_vendor/requests/packages/urllib3/poolmanager.py
index f13e673d1..1023dcba3 100644
--- a/pip/_vendor/requests/packages/urllib3/poolmanager.py
+++ b/pip/_vendor/requests/packages/urllib3/poolmanager.py
@@ -18,16 +18,16 @@ from .util.retry import Retry
__all__ = ['PoolManager', 'ProxyManager', 'proxy_from_url']
-pool_classes_by_scheme = {
- 'http': HTTPConnectionPool,
- 'https': HTTPSConnectionPool,
-}
-
log = logging.getLogger(__name__)
SSL_KEYWORDS = ('key_file', 'cert_file', 'cert_reqs', 'ca_certs',
'ssl_version', 'ca_cert_dir')
+pool_classes_by_scheme = {
+ 'http': HTTPConnectionPool,
+ 'https': HTTPSConnectionPool,
+}
+
class PoolManager(RequestMethods):
"""
@@ -65,6 +65,9 @@ class PoolManager(RequestMethods):
self.pools = RecentlyUsedContainer(num_pools,
dispose_func=lambda p: p.close())
+ # Locally set the pool classes so other PoolManagers can override them.
+ self.pool_classes_by_scheme = pool_classes_by_scheme
+
def __enter__(self):
return self
@@ -81,7 +84,7 @@ class PoolManager(RequestMethods):
by :meth:`connection_from_url` and companion methods. It is intended
to be overridden for customization.
"""
- pool_cls = pool_classes_by_scheme[scheme]
+ pool_cls = self.pool_classes_by_scheme[scheme]
kwargs = self.connection_pool_kw
if scheme == 'http':
kwargs = self.connection_pool_kw.copy()
@@ -186,7 +189,7 @@ class PoolManager(RequestMethods):
kw['retries'] = retries
kw['redirect'] = redirect
- log.info("Redirecting %s -> %s" % (url, redirect_location))
+ log.info("Redirecting %s -> %s", url, redirect_location)
return self.urlopen(method, redirect_location, **kw)
diff --git a/pip/_vendor/requests/packages/urllib3/response.py b/pip/_vendor/requests/packages/urllib3/response.py
index 8f2a1b5c2..ac1b2f19e 100644
--- a/pip/_vendor/requests/packages/urllib3/response.py
+++ b/pip/_vendor/requests/packages/urllib3/response.py
@@ -221,6 +221,8 @@ class HTTPResponse(io.IOBase):
On exit, release the connection back to the pool.
"""
+ clean_exit = False
+
try:
try:
yield
@@ -243,20 +245,27 @@ class HTTPResponse(io.IOBase):
# This includes IncompleteRead.
raise ProtocolError('Connection broken: %r' % e, e)
- except Exception:
- # The response may not be closed but we're not going to use it anymore
- # so close it now to ensure that the connection is released back to the pool.
- if self._original_response and not self._original_response.isclosed():
- self._original_response.close()
-
- # Closing the response may not actually be sufficient to close
- # everything, so if we have a hold of the connection close that
- # too.
- if self._connection is not None:
- self._connection.close()
-
- raise
+ # If no exception is thrown, we should avoid cleaning up
+ # unnecessarily.
+ clean_exit = True
finally:
+ # If we didn't terminate cleanly, we need to throw away our
+ # connection.
+ if not clean_exit:
+ # The response may not be closed but we're not going to use it
+ # anymore so close it now to ensure that the connection is
+ # released back to the pool.
+ if self._original_response:
+ self._original_response.close()
+
+ # Closing the response may not actually be sufficient to close
+ # everything, so if we have a hold of the connection close that
+ # too.
+ if self._connection:
+ self._connection.close()
+
+ # If we hold the original response but it's closed now, we should
+ # return the connection back to the pool.
if self._original_response and self._original_response.isclosed():
self.release_conn()
@@ -387,6 +396,9 @@ class HTTPResponse(io.IOBase):
if not self.closed:
self._fp.close()
+ if self._connection:
+ self._connection.close()
+
@property
def closed(self):
if self._fp is None:
diff --git a/pip/_vendor/requests/packages/urllib3/util/__init__.py b/pip/_vendor/requests/packages/urllib3/util/__init__.py
index c6c6243cf..4778cf996 100644
--- a/pip/_vendor/requests/packages/urllib3/util/__init__.py
+++ b/pip/_vendor/requests/packages/urllib3/util/__init__.py
@@ -6,6 +6,7 @@ from .response import is_fp_closed
from .ssl_ import (
SSLContext,
HAS_SNI,
+ IS_PYOPENSSL,
assert_fingerprint,
resolve_cert_reqs,
resolve_ssl_version,
@@ -26,6 +27,7 @@ from .url import (
__all__ = (
'HAS_SNI',
+ 'IS_PYOPENSSL',
'SSLContext',
'Retry',
'Timeout',
diff --git a/pip/_vendor/requests/packages/urllib3/util/response.py b/pip/_vendor/requests/packages/urllib3/util/response.py
index bc7232720..0b5c75c13 100644
--- a/pip/_vendor/requests/packages/urllib3/util/response.py
+++ b/pip/_vendor/requests/packages/urllib3/util/response.py
@@ -61,7 +61,7 @@ def assert_header_parsing(headers):
def is_response_to_head(response):
"""
- Checks, wether a the request of a response has been a HEAD-request.
+ Checks whether the request of a response has been a HEAD-request.
Handles the quirks of AppEngine.
:param conn:
diff --git a/pip/_vendor/requests/packages/urllib3/util/retry.py b/pip/_vendor/requests/packages/urllib3/util/retry.py
index 03a01249d..2d3aa20d0 100644
--- a/pip/_vendor/requests/packages/urllib3/util/retry.py
+++ b/pip/_vendor/requests/packages/urllib3/util/retry.py
@@ -102,6 +102,11 @@ class Retry(object):
:param bool raise_on_redirect: Whether, if the number of redirects is
exhausted, to raise a MaxRetryError, or to return a response with a
response code in the 3xx range.
+
+ :param bool raise_on_status: Similar meaning to ``raise_on_redirect``:
+ whether we should raise an exception, or return a response,
+ if status falls in ``status_forcelist`` range and retries have
+ been exhausted.
"""
DEFAULT_METHOD_WHITELIST = frozenset([
@@ -112,7 +117,8 @@ class Retry(object):
def __init__(self, total=10, connect=None, read=None, redirect=None,
method_whitelist=DEFAULT_METHOD_WHITELIST, status_forcelist=None,
- backoff_factor=0, raise_on_redirect=True, _observed_errors=0):
+ backoff_factor=0, raise_on_redirect=True, raise_on_status=True,
+ _observed_errors=0):
self.total = total
self.connect = connect
@@ -127,6 +133,7 @@ class Retry(object):
self.method_whitelist = method_whitelist
self.backoff_factor = backoff_factor
self.raise_on_redirect = raise_on_redirect
+ self.raise_on_status = raise_on_status
self._observed_errors = _observed_errors # TODO: use .history instead?
def new(self, **kw):
@@ -137,6 +144,7 @@ class Retry(object):
status_forcelist=self.status_forcelist,
backoff_factor=self.backoff_factor,
raise_on_redirect=self.raise_on_redirect,
+ raise_on_status=self.raise_on_status,
_observed_errors=self._observed_errors,
)
params.update(kw)
@@ -153,7 +161,7 @@ class Retry(object):
redirect = bool(redirect) and None
new_retries = cls(retries, redirect=redirect)
- log.debug("Converted retries value: %r -> %r" % (retries, new_retries))
+ log.debug("Converted retries value: %r -> %r", retries, new_retries)
return new_retries
def get_backoff_time(self):
@@ -272,7 +280,7 @@ class Retry(object):
if new_retry.is_exhausted():
raise MaxRetryError(_pool, url, error or ResponseError(cause))
- log.debug("Incremented Retry for (url='%s'): %r" % (url, new_retry))
+ log.debug("Incremented Retry for (url='%s'): %r", url, new_retry)
return new_retry
diff --git a/pip/_vendor/requests/packages/urllib3/util/ssl_.py b/pip/_vendor/requests/packages/urllib3/util/ssl_.py
index 67f83441e..e8d9e7d29 100644
--- a/pip/_vendor/requests/packages/urllib3/util/ssl_.py
+++ b/pip/_vendor/requests/packages/urllib3/util/ssl_.py
@@ -12,6 +12,7 @@ from ..exceptions import SSLError, InsecurePlatformWarning, SNIMissingWarning
SSLContext = None
HAS_SNI = False
create_default_context = None
+IS_PYOPENSSL = False
# Maps the length of a digest to a possible hash function producing this digest
HASHFUNC_MAP = {
@@ -110,11 +111,12 @@ except ImportError:
)
self.ciphers = cipher_suite
- def wrap_socket(self, socket, server_hostname=None):
+ def wrap_socket(self, socket, server_hostname=None, server_side=False):
warnings.warn(
'A true SSLContext object is not available. This prevents '
'urllib3 from configuring SSL appropriately and may cause '
- 'certain SSL connections to fail. For more information, see '
+ 'certain SSL connections to fail. You can upgrade to a newer '
+ 'version of Python to solve this. For more information, see '
'https://urllib3.readthedocs.org/en/latest/security.html'
'#insecureplatformwarning.',
InsecurePlatformWarning
@@ -125,6 +127,7 @@ except ImportError:
'ca_certs': self.ca_certs,
'cert_reqs': self.verify_mode,
'ssl_version': self.protocol,
+ 'server_side': server_side,
}
if self.supports_set_ciphers: # Platform-specific: Python 2.7+
return wrap_socket(socket, ciphers=self.ciphers, **kwargs)
@@ -308,8 +311,8 @@ def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
'An HTTPS request has been made, but the SNI (Subject Name '
'Indication) extension to TLS is not available on this platform. '
'This may cause the server to present an incorrect TLS '
- 'certificate, which can cause validation failures. For more '
- 'information, see '
+ 'certificate, which can cause validation failures. You can upgrade to '
+ 'a newer version of Python to solve this. For more information, see '
'https://urllib3.readthedocs.org/en/latest/security.html'
'#snimissingwarning.',
SNIMissingWarning
diff --git a/pip/_vendor/requests/sessions.py b/pip/_vendor/requests/sessions.py
index 9eaa36ae4..45be9733e 100644
--- a/pip/_vendor/requests/sessions.py
+++ b/pip/_vendor/requests/sessions.py
@@ -110,13 +110,12 @@ class SessionRedirectMixin(object):
resp.raw.read(decode_content=False)
if i >= self.max_redirects:
- raise TooManyRedirects('Exceeded %s redirects.' % self.max_redirects)
+ raise TooManyRedirects('Exceeded %s redirects.' % self.max_redirects, response=resp)
# Release the connection back into the pool.
resp.close()
url = resp.headers['location']
- method = req.method
# Handle redirection without scheme (see: RFC 1808 Section 4)
if url.startswith('//'):
@@ -140,22 +139,7 @@ class SessionRedirectMixin(object):
if resp.is_permanent_redirect and req.url != prepared_request.url:
self.redirect_cache[req.url] = prepared_request.url
- # http://tools.ietf.org/html/rfc7231#section-6.4.4
- if (resp.status_code == codes.see_other and
- method != 'HEAD'):
- method = 'GET'
-
- # Do what the browsers do, despite standards...
- # First, turn 302s into GETs.
- if resp.status_code == codes.found and method != 'HEAD':
- method = 'GET'
-
- # Second, if a POST is responded to with a 301, turn it into a GET.
- # This bizarre behaviour is explained in Issue 1704.
- if resp.status_code == codes.moved and method == 'POST':
- method = 'GET'
-
- prepared_request.method = method
+ self.rebuild_method(prepared_request, resp)
# https://github.com/kennethreitz/requests/issues/1084
if resp.status_code not in (codes.temporary_redirect, codes.permanent_redirect):
@@ -262,6 +246,28 @@ class SessionRedirectMixin(object):
return new_proxies
+ def rebuild_method(self, prepared_request, response):
+ """When being redirected we may want to change the method of the request
+ based on certain specs or browser behavior.
+ """
+ method = prepared_request.method
+
+ # http://tools.ietf.org/html/rfc7231#section-6.4.4
+ if response.status_code == codes.see_other and method != 'HEAD':
+ method = 'GET'
+
+ # Do what the browsers do, despite standards...
+ # First, turn 302s into GETs.
+ if response.status_code == codes.found and method != 'HEAD':
+ method = 'GET'
+
+ # Second, if a POST is responded to with a 301, turn it into a GET.
+ # This bizarre behaviour is explained in Issue 1704.
+ if response.status_code == codes.moved and method == 'POST':
+ method = 'GET'
+
+ prepared_request.method = method
+
class Session(SessionRedirectMixin):
"""A Requests session.
@@ -437,7 +443,8 @@ class Session(SessionRedirectMixin):
A CA_BUNDLE path can also be provided. Defaults to ``True``.
:param cert: (optional) if String, path to ssl client cert file (.pem).
If Tuple, ('cert', 'key') pair.
- """
+ :rtype: requests.Response
+ """
# Create the Request.
req = Request(
method = method.upper(),
@@ -550,22 +557,24 @@ class Session(SessionRedirectMixin):
# It's possible that users might accidentally send a Request object.
# Guard against that specific failure case.
- if not isinstance(request, PreparedRequest):
+ if isinstance(request, Request):
raise ValueError('You can only send PreparedRequests.')
- checked_urls = set()
- while request.url in self.redirect_cache:
- checked_urls.add(request.url)
- new_url = self.redirect_cache.get(request.url)
- if new_url in checked_urls:
- break
- request.url = new_url
-
# Set up variables needed for resolve_redirects and dispatching of hooks
allow_redirects = kwargs.pop('allow_redirects', True)
stream = kwargs.get('stream')
hooks = request.hooks
+ # Resolve URL in redirect cache, if available.
+ if allow_redirects:
+ checked_urls = set()
+ while request.url in self.redirect_cache:
+ checked_urls.add(request.url)
+ new_url = self.redirect_cache.get(request.url)
+ if new_url in checked_urls:
+ break
+ request.url = new_url
+
# Get the appropriate adapter to use
adapter = self.get_adapter(url=request.url)
diff --git a/pip/_vendor/requests/status_codes.py b/pip/_vendor/requests/status_codes.py
index a852574a4..0137c91d9 100644
--- a/pip/_vendor/requests/status_codes.py
+++ b/pip/_vendor/requests/status_codes.py
@@ -53,6 +53,7 @@ _codes = {
416: ('requested_range_not_satisfiable', 'requested_range', 'range_not_satisfiable'),
417: ('expectation_failed',),
418: ('im_a_teapot', 'teapot', 'i_am_a_teapot'),
+ 421: ('misdirected_request',),
422: ('unprocessable_entity', 'unprocessable'),
423: ('locked',),
424: ('failed_dependency', 'dependency'),
diff --git a/pip/_vendor/requests/structures.py b/pip/_vendor/requests/structures.py
index 3e5f2faa2..991056e47 100644
--- a/pip/_vendor/requests/structures.py
+++ b/pip/_vendor/requests/structures.py
@@ -10,6 +10,8 @@ Data structures that power Requests.
import collections
+from .compat import OrderedDict
+
class CaseInsensitiveDict(collections.MutableMapping):
"""
@@ -40,7 +42,7 @@ class CaseInsensitiveDict(collections.MutableMapping):
"""
def __init__(self, data=None, **kwargs):
- self._store = dict()
+ self._store = OrderedDict()
if data is None:
data = {}
self.update(data, **kwargs)
diff --git a/pip/_vendor/requests/utils.py b/pip/_vendor/requests/utils.py
index c5c3fd01d..c08448ccb 100644
--- a/pip/_vendor/requests/utils.py
+++ b/pip/_vendor/requests/utils.py
@@ -14,9 +14,7 @@ import codecs
import collections
import io
import os
-import platform
import re
-import sys
import socket
import struct
import warnings
@@ -83,7 +81,14 @@ def super_len(o):
)
if hasattr(o, 'tell'):
- current_position = o.tell()
+ try:
+ current_position = o.tell()
+ except (OSError, IOError):
+ # This can happen in some weird situations, such as when the file
+ # is actually a special file descriptor like stdin. In this
+ # instance, we don't know what the length is, so set it to zero and
+ # let requests chunk it instead.
+ current_position = total_length
return max(0, total_length - current_position)
@@ -557,6 +562,7 @@ def should_bypass_proxies(url):
return False
+
def get_environ_proxies(url):
"""Return a dict of environment proxies."""
if should_bypass_proxies(url):
@@ -564,6 +570,7 @@ def get_environ_proxies(url):
else:
return getproxies()
+
def select_proxy(url, proxies):
"""Select a proxy for the url, if applicable.
@@ -572,11 +579,15 @@ def select_proxy(url, proxies):
"""
proxies = proxies or {}
urlparts = urlparse(url)
- proxy = proxies.get(urlparts.scheme+'://'+urlparts.hostname)
+ if urlparts.hostname is None:
+ proxy = None
+ else:
+ proxy = proxies.get(urlparts.scheme+'://'+urlparts.hostname)
if proxy is None:
proxy = proxies.get(urlparts.scheme)
return proxy
+
def default_user_agent(name="python-requests"):
"""Return a string representing the default user agent."""
return '%s/%s' % (name, __version__)
@@ -600,21 +611,19 @@ def parse_header_links(value):
links = []
- replace_chars = " '\""
+ replace_chars = ' \'"'
- for val in re.split(", *<", value):
+ for val in re.split(', *<', value):
try:
- url, params = val.split(";", 1)
+ url, params = val.split(';', 1)
except ValueError:
url, params = val, ''
- link = {}
-
- link["url"] = url.strip("<> '\"")
+ link = {'url': url.strip('<> \'"')}
- for param in params.split(";"):
+ for param in params.split(';'):
try:
- key, value = param.split("=")
+ key, value = param.split('=')
except ValueError:
break
@@ -661,8 +670,8 @@ def guess_json_utf(data):
def prepend_scheme_if_needed(url, new_scheme):
- '''Given a URL that may or may not have a scheme, prepend the given scheme.
- Does not replace a present scheme with the one provided as an argument.'''
+ """Given a URL that may or may not have a scheme, prepend the given scheme.
+ Does not replace a present scheme with the one provided as an argument."""
scheme, netloc, path, params, query, fragment = urlparse(url, new_scheme)
# urlparse is a finicky beast, and sometimes decides that there isn't a
@@ -693,8 +702,6 @@ def to_native_string(string, encoding='ascii'):
string in the native string type, encoding and decoding where necessary.
This assumes ASCII unless told otherwise.
"""
- out = None
-
if isinstance(string, builtin_str):
out = string
else:
diff --git a/pip/_vendor/vendor.txt b/pip/_vendor/vendor.txt
index 5d4db70ad..c2917c288 100644
--- a/pip/_vendor/vendor.txt
+++ b/pip/_vendor/vendor.txt
@@ -1,12 +1,12 @@
-distlib==0.2.2
-html5lib==1.0b8
-six==1.10.0
-colorama==0.3.6
-requests==2.9.1
-CacheControl==0.11.6
-lockfile==0.12.2
-progress==1.2
-ipaddress==1.0.16 # Only needed on 2.6 and 2.7
-packaging==16.7
-pyparsing==2.1.0
-retrying==1.3.3
+distlib==0.2.3
+html5lib==1.0b8
+six==1.10.0
+colorama==0.3.7
+requests==2.10.0
+CacheControl==0.11.6
+lockfile==0.12.2
+progress==1.2
+ipaddress==1.0.16 # Only needed on 2.6 and 2.7
+packaging==16.7
+pyparsing==2.1.1
+retrying==1.3.3