mirror of https://github.com/pypa/pip
Update requests to 2.19.1
This commit is contained in:
parent
7b97a38c6b
commit
7ccc1a8f34
|
@ -0,0 +1 @@
|
||||||
|
Update requests to 2.19.1
|
|
@ -57,10 +57,10 @@ def check_compatibility(urllib3_version, chardet_version):
|
||||||
# Check urllib3 for compatibility.
|
# Check urllib3 for compatibility.
|
||||||
major, minor, patch = urllib3_version # noqa: F811
|
major, minor, patch = urllib3_version # noqa: F811
|
||||||
major, minor, patch = int(major), int(minor), int(patch)
|
major, minor, patch = int(major), int(minor), int(patch)
|
||||||
# urllib3 >= 1.21.1, <= 1.22
|
# urllib3 >= 1.21.1, <= 1.23
|
||||||
assert major == 1
|
assert major == 1
|
||||||
assert minor >= 21
|
assert minor >= 21
|
||||||
assert minor <= 22
|
assert minor <= 23
|
||||||
|
|
||||||
# Check chardet for compatibility.
|
# Check chardet for compatibility.
|
||||||
major, minor, patch = chardet_version.split('.')[:3]
|
major, minor, patch = chardet_version.split('.')[:3]
|
||||||
|
@ -71,6 +71,17 @@ def check_compatibility(urllib3_version, chardet_version):
|
||||||
assert patch >= 2
|
assert patch >= 2
|
||||||
|
|
||||||
|
|
||||||
|
def _check_cryptography(cryptography_version):
|
||||||
|
# cryptography < 1.3.4
|
||||||
|
try:
|
||||||
|
cryptography_version = list(map(int, cryptography_version.split('.')))
|
||||||
|
except ValueError:
|
||||||
|
return
|
||||||
|
|
||||||
|
if cryptography_version < [1, 3, 4]:
|
||||||
|
warning = 'Old version of cryptography ({0}) may cause slowdown.'.format(cryptography_version)
|
||||||
|
warnings.warn(warning, RequestsDependencyWarning)
|
||||||
|
|
||||||
# Check imported dependencies for compatibility.
|
# Check imported dependencies for compatibility.
|
||||||
try:
|
try:
|
||||||
check_compatibility(urllib3.__version__, chardet.__version__)
|
check_compatibility(urllib3.__version__, chardet.__version__)
|
||||||
|
@ -85,6 +96,10 @@ if not WINDOWS:
|
||||||
try:
|
try:
|
||||||
from pip._vendor.urllib3.contrib import pyopenssl
|
from pip._vendor.urllib3.contrib import pyopenssl
|
||||||
pyopenssl.inject_into_urllib3()
|
pyopenssl.inject_into_urllib3()
|
||||||
|
|
||||||
|
# Check cryptography version
|
||||||
|
from cryptography import __version__ as cryptography_version
|
||||||
|
_check_cryptography(cryptography_version)
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,10 @@
|
||||||
__title__ = 'requests'
|
__title__ = 'requests'
|
||||||
__description__ = 'Python HTTP for Humans.'
|
__description__ = 'Python HTTP for Humans.'
|
||||||
__url__ = 'http://python-requests.org'
|
__url__ = 'http://python-requests.org'
|
||||||
__version__ = '2.18.4'
|
__version__ = '2.19.1'
|
||||||
__build__ = 0x021804
|
__build__ = 0x021901
|
||||||
__author__ = 'Kenneth Reitz'
|
__author__ = 'Kenneth Reitz'
|
||||||
__author_email__ = 'me@kennethreitz.org'
|
__author_email__ = 'me@kennethreitz.org'
|
||||||
__license__ = 'Apache 2.0'
|
__license__ = 'Apache 2.0'
|
||||||
__copyright__ = 'Copyright 2017 Kenneth Reitz'
|
__copyright__ = 'Copyright 2018 Kenneth Reitz'
|
||||||
__cake__ = u'\u2728 \U0001f370 \u2728'
|
__cake__ = u'\u2728 \U0001f370 \u2728'
|
||||||
|
|
|
@ -13,6 +13,7 @@ import socket
|
||||||
|
|
||||||
from pip._vendor.urllib3.poolmanager import PoolManager, proxy_from_url
|
from pip._vendor.urllib3.poolmanager import PoolManager, proxy_from_url
|
||||||
from pip._vendor.urllib3.response import HTTPResponse
|
from pip._vendor.urllib3.response import HTTPResponse
|
||||||
|
from pip._vendor.urllib3.util import parse_url
|
||||||
from pip._vendor.urllib3.util import Timeout as TimeoutSauce
|
from pip._vendor.urllib3.util import Timeout as TimeoutSauce
|
||||||
from pip._vendor.urllib3.util.retry import Retry
|
from pip._vendor.urllib3.util.retry import Retry
|
||||||
from pip._vendor.urllib3.exceptions import ClosedPoolError
|
from pip._vendor.urllib3.exceptions import ClosedPoolError
|
||||||
|
@ -28,13 +29,13 @@ from pip._vendor.urllib3.exceptions import ResponseError
|
||||||
|
|
||||||
from .models import Response
|
from .models import Response
|
||||||
from .compat import urlparse, basestring
|
from .compat import urlparse, basestring
|
||||||
from .utils import (DEFAULT_CA_BUNDLE_PATH, get_encoding_from_headers,
|
from .utils import (DEFAULT_CA_BUNDLE_PATH, extract_zipped_paths,
|
||||||
prepend_scheme_if_needed, get_auth_from_url, urldefragauth,
|
get_encoding_from_headers, prepend_scheme_if_needed,
|
||||||
select_proxy)
|
get_auth_from_url, urldefragauth, select_proxy)
|
||||||
from .structures import CaseInsensitiveDict
|
from .structures import CaseInsensitiveDict
|
||||||
from .cookies import extract_cookies_to_jar
|
from .cookies import extract_cookies_to_jar
|
||||||
from .exceptions import (ConnectionError, ConnectTimeout, ReadTimeout, SSLError,
|
from .exceptions import (ConnectionError, ConnectTimeout, ReadTimeout, SSLError,
|
||||||
ProxyError, RetryError, InvalidSchema)
|
ProxyError, RetryError, InvalidSchema, InvalidProxyURL)
|
||||||
from .auth import _basic_auth_str
|
from .auth import _basic_auth_str
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -219,7 +220,7 @@ class HTTPAdapter(BaseAdapter):
|
||||||
cert_loc = verify
|
cert_loc = verify
|
||||||
|
|
||||||
if not cert_loc:
|
if not cert_loc:
|
||||||
cert_loc = DEFAULT_CA_BUNDLE_PATH
|
cert_loc = extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH)
|
||||||
|
|
||||||
if not cert_loc or not os.path.exists(cert_loc):
|
if not cert_loc or not os.path.exists(cert_loc):
|
||||||
raise IOError("Could not find a suitable TLS CA certificate bundle, "
|
raise IOError("Could not find a suitable TLS CA certificate bundle, "
|
||||||
|
@ -300,6 +301,10 @@ class HTTPAdapter(BaseAdapter):
|
||||||
|
|
||||||
if proxy:
|
if proxy:
|
||||||
proxy = prepend_scheme_if_needed(proxy, 'http')
|
proxy = prepend_scheme_if_needed(proxy, 'http')
|
||||||
|
proxy_url = parse_url(proxy)
|
||||||
|
if not proxy_url.host:
|
||||||
|
raise InvalidProxyURL("Please check proxy URL. It is malformed"
|
||||||
|
" and could be missing the host.")
|
||||||
proxy_manager = self.proxy_manager_for(proxy)
|
proxy_manager = self.proxy_manager_for(proxy)
|
||||||
conn = proxy_manager.connection_from_url(url)
|
conn = proxy_manager.connection_from_url(url)
|
||||||
else:
|
else:
|
||||||
|
@ -406,7 +411,7 @@ class HTTPAdapter(BaseAdapter):
|
||||||
|
|
||||||
self.cert_verify(conn, request.url, verify, cert)
|
self.cert_verify(conn, request.url, verify, cert)
|
||||||
url = self.request_url(request, proxies)
|
url = self.request_url(request, proxies)
|
||||||
self.add_headers(request)
|
self.add_headers(request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies)
|
||||||
|
|
||||||
chunked = not (request.body is None or 'Content-Length' in request.headers)
|
chunked = not (request.body is None or 'Content-Length' in request.headers)
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ def request(method, url, **kwargs):
|
||||||
:param url: URL for the new :class:`Request` object.
|
:param url: URL for the new :class:`Request` object.
|
||||||
:param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`.
|
:param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`.
|
||||||
:param data: (optional) Dictionary or list of tuples ``[(key, value)]`` (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`.
|
:param data: (optional) Dictionary or list of tuples ``[(key, value)]`` (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`.
|
||||||
:param json: (optional) json data to send in the body of the :class:`Request`.
|
:param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
|
||||||
:param headers: (optional) Dictionary of HTTP Headers to send with 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 cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
|
||||||
:param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.
|
:param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.
|
||||||
|
|
|
@ -153,6 +153,18 @@ class HTTPDigestAuth(AuthBase):
|
||||||
x = x.encode('utf-8')
|
x = x.encode('utf-8')
|
||||||
return hashlib.sha1(x).hexdigest()
|
return hashlib.sha1(x).hexdigest()
|
||||||
hash_utf8 = sha_utf8
|
hash_utf8 = sha_utf8
|
||||||
|
elif _algorithm == 'SHA-256':
|
||||||
|
def sha256_utf8(x):
|
||||||
|
if isinstance(x, str):
|
||||||
|
x = x.encode('utf-8')
|
||||||
|
return hashlib.sha256(x).hexdigest()
|
||||||
|
hash_utf8 = sha256_utf8
|
||||||
|
elif _algorithm == 'SHA-512':
|
||||||
|
def sha512_utf8(x):
|
||||||
|
if isinstance(x, str):
|
||||||
|
x = x.encode('utf-8')
|
||||||
|
return hashlib.sha512(x).hexdigest()
|
||||||
|
hash_utf8 = sha512_utf8
|
||||||
|
|
||||||
KD = lambda s, d: hash_utf8("%s:%s" % (s, d))
|
KD = lambda s, d: hash_utf8("%s:%s" % (s, d))
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ if is_py2:
|
||||||
import cookielib
|
import cookielib
|
||||||
from Cookie import Morsel
|
from Cookie import Morsel
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
|
from collections import Callable, Mapping, MutableMapping
|
||||||
|
|
||||||
from pip._vendor.urllib3.packages.ordered_dict import OrderedDict
|
from pip._vendor.urllib3.packages.ordered_dict import OrderedDict
|
||||||
|
|
||||||
|
@ -64,6 +65,7 @@ elif is_py3:
|
||||||
from http.cookies import Morsel
|
from http.cookies import Morsel
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
from collections.abc import Callable, Mapping, MutableMapping
|
||||||
|
|
||||||
builtin_str = str
|
builtin_str = str
|
||||||
str = str
|
str = str
|
||||||
|
|
|
@ -12,10 +12,9 @@ requests.utils imports from here, so be careful with imports.
|
||||||
import copy
|
import copy
|
||||||
import time
|
import time
|
||||||
import calendar
|
import calendar
|
||||||
import collections
|
|
||||||
|
|
||||||
from ._internal_utils import to_native_string
|
from ._internal_utils import to_native_string
|
||||||
from .compat import cookielib, urlparse, urlunparse, Morsel
|
from .compat import cookielib, urlparse, urlunparse, Morsel, MutableMapping
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import threading
|
import threading
|
||||||
|
@ -169,7 +168,7 @@ class CookieConflictError(RuntimeError):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
|
class RequestsCookieJar(cookielib.CookieJar, MutableMapping):
|
||||||
"""Compatibility class; is a cookielib.CookieJar, but exposes a dict
|
"""Compatibility class; is a cookielib.CookieJar, but exposes a dict
|
||||||
interface.
|
interface.
|
||||||
|
|
||||||
|
@ -415,9 +414,14 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
|
||||||
def copy(self):
|
def copy(self):
|
||||||
"""Return a copy of this RequestsCookieJar."""
|
"""Return a copy of this RequestsCookieJar."""
|
||||||
new_cj = RequestsCookieJar()
|
new_cj = RequestsCookieJar()
|
||||||
|
new_cj.set_policy(self.get_policy())
|
||||||
new_cj.update(self)
|
new_cj.update(self)
|
||||||
return new_cj
|
return new_cj
|
||||||
|
|
||||||
|
def get_policy(self):
|
||||||
|
"""Return the CookiePolicy instance used."""
|
||||||
|
return self._policy
|
||||||
|
|
||||||
|
|
||||||
def _copy_cookie_jar(jar):
|
def _copy_cookie_jar(jar):
|
||||||
if jar is None:
|
if jar is None:
|
||||||
|
|
|
@ -85,6 +85,10 @@ class InvalidHeader(RequestException, ValueError):
|
||||||
"""The header value provided was somehow invalid."""
|
"""The header value provided was somehow invalid."""
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidProxyURL(InvalidURL):
|
||||||
|
"""The proxy URL provided is invalid."""
|
||||||
|
|
||||||
|
|
||||||
class ChunkedEncodingError(RequestException):
|
class ChunkedEncodingError(RequestException):
|
||||||
"""The server declared chunked encoding but sent an invalid chunk."""
|
"""The server declared chunked encoding but sent an invalid chunk."""
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ from pip._vendor import chardet
|
||||||
from . import __version__ as requests_version
|
from . import __version__ as requests_version
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from .packages.urllib3.contrib import pyopenssl
|
from pip._vendor.urllib3.contrib import pyopenssl
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pyopenssl = None
|
pyopenssl = None
|
||||||
OpenSSL = None
|
OpenSSL = None
|
||||||
|
|
|
@ -7,7 +7,6 @@ requests.models
|
||||||
This module contains the primary objects that power Requests.
|
This module contains the primary objects that power Requests.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import collections
|
|
||||||
import datetime
|
import datetime
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
@ -37,6 +36,7 @@ from .utils import (
|
||||||
stream_decode_response_unicode, to_key_val_list, parse_header_links,
|
stream_decode_response_unicode, to_key_val_list, parse_header_links,
|
||||||
iter_slices, guess_json_utf, super_len, check_header_validity)
|
iter_slices, guess_json_utf, super_len, check_header_validity)
|
||||||
from .compat import (
|
from .compat import (
|
||||||
|
Callable, Mapping,
|
||||||
cookielib, urlunparse, urlsplit, urlencode, str, bytes,
|
cookielib, urlunparse, urlsplit, urlencode, str, bytes,
|
||||||
is_py2, chardet, builtin_str, basestring)
|
is_py2, chardet, builtin_str, basestring)
|
||||||
from .compat import json as complexjson
|
from .compat import json as complexjson
|
||||||
|
@ -155,8 +155,12 @@ class RequestEncodingMixin(object):
|
||||||
|
|
||||||
if isinstance(fp, (str, bytes, bytearray)):
|
if isinstance(fp, (str, bytes, bytearray)):
|
||||||
fdata = fp
|
fdata = fp
|
||||||
else:
|
elif hasattr(fp, 'read'):
|
||||||
fdata = fp.read()
|
fdata = fp.read()
|
||||||
|
elif fp is None:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
fdata = fp
|
||||||
|
|
||||||
rf = RequestField(name=k, data=fdata, filename=fn, headers=fh)
|
rf = RequestField(name=k, data=fdata, filename=fn, headers=fh)
|
||||||
rf.make_multipart(content_type=ft)
|
rf.make_multipart(content_type=ft)
|
||||||
|
@ -174,10 +178,10 @@ class RequestHooksMixin(object):
|
||||||
if event not in self.hooks:
|
if event not in self.hooks:
|
||||||
raise ValueError('Unsupported event specified, with event name "%s"' % (event))
|
raise ValueError('Unsupported event specified, with event name "%s"' % (event))
|
||||||
|
|
||||||
if isinstance(hook, collections.Callable):
|
if isinstance(hook, Callable):
|
||||||
self.hooks[event].append(hook)
|
self.hooks[event].append(hook)
|
||||||
elif hasattr(hook, '__iter__'):
|
elif hasattr(hook, '__iter__'):
|
||||||
self.hooks[event].extend(h for h in hook if isinstance(h, collections.Callable))
|
self.hooks[event].extend(h for h in hook if isinstance(h, Callable))
|
||||||
|
|
||||||
def deregister_hook(self, event, hook):
|
def deregister_hook(self, event, hook):
|
||||||
"""Deregister a previously registered hook.
|
"""Deregister a previously registered hook.
|
||||||
|
@ -461,7 +465,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
|
||||||
|
|
||||||
is_stream = all([
|
is_stream = all([
|
||||||
hasattr(data, '__iter__'),
|
hasattr(data, '__iter__'),
|
||||||
not isinstance(data, (basestring, list, tuple, collections.Mapping))
|
not isinstance(data, (basestring, list, tuple, Mapping))
|
||||||
])
|
])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -686,11 +690,11 @@ class Response(object):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ok(self):
|
def ok(self):
|
||||||
"""Returns True if :attr:`status_code` is less than 400.
|
"""Returns True if :attr:`status_code` is less than 400, False if not.
|
||||||
|
|
||||||
This attribute checks if the status code of the response is between
|
This attribute checks if the status code of the response is between
|
||||||
400 and 600 to see if there was a client error or a server error. If
|
400 and 600 to see if there was a client error or a server error. If
|
||||||
the status code, is between 200 and 400, this will return True. This
|
the status code is between 200 and 400, this will return True. This
|
||||||
is **not** a check to see if the response code is ``200 OK``.
|
is **not** a check to see if the response code is ``200 OK``.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
@ -820,7 +824,7 @@ class Response(object):
|
||||||
if self.status_code == 0 or self.raw is None:
|
if self.status_code == 0 or self.raw is None:
|
||||||
self._content = None
|
self._content = None
|
||||||
else:
|
else:
|
||||||
self._content = bytes().join(self.iter_content(CONTENT_CHUNK_SIZE)) or bytes()
|
self._content = b''.join(self.iter_content(CONTENT_CHUNK_SIZE)) or b''
|
||||||
|
|
||||||
self._content_consumed = True
|
self._content_consumed = True
|
||||||
# don't need to release the connection; that's been handled by urllib3
|
# don't need to release the connection; that's been handled by urllib3
|
||||||
|
|
|
@ -8,13 +8,12 @@ This module provides a Session object to manage and persist settings across
|
||||||
requests (cookies, auth, proxies).
|
requests (cookies, auth, proxies).
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import platform
|
import sys
|
||||||
import time
|
import time
|
||||||
from collections import Mapping
|
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
from .auth import _basic_auth_str
|
from .auth import _basic_auth_str
|
||||||
from .compat import cookielib, is_py3, OrderedDict, urljoin, urlparse
|
from .compat import cookielib, is_py3, OrderedDict, urljoin, urlparse, Mapping
|
||||||
from .cookies import (
|
from .cookies import (
|
||||||
cookiejar_from_dict, extract_cookies_to_jar, RequestsCookieJar, merge_cookies)
|
cookiejar_from_dict, extract_cookies_to_jar, RequestsCookieJar, merge_cookies)
|
||||||
from .models import Request, PreparedRequest, DEFAULT_REDIRECT_LIMIT
|
from .models import Request, PreparedRequest, DEFAULT_REDIRECT_LIMIT
|
||||||
|
@ -38,8 +37,8 @@ from .status_codes import codes
|
||||||
from .models import REDIRECT_STATI
|
from .models import REDIRECT_STATI
|
||||||
|
|
||||||
# Preferred clock, based on which one is more accurate on a given system.
|
# Preferred clock, based on which one is more accurate on a given system.
|
||||||
if platform.system() == 'Windows':
|
if sys.platform == 'win32':
|
||||||
try: # Python 3.3+
|
try: # Python 3.4+
|
||||||
preferred_clock = time.perf_counter
|
preferred_clock = time.perf_counter
|
||||||
except AttributeError: # Earlier than Python 3.
|
except AttributeError: # Earlier than Python 3.
|
||||||
preferred_clock = time.clock
|
preferred_clock = time.clock
|
||||||
|
@ -123,6 +122,7 @@ class SessionRedirectMixin(object):
|
||||||
hist = [] # keep track of history
|
hist = [] # keep track of history
|
||||||
|
|
||||||
url = self.get_redirect_target(resp)
|
url = self.get_redirect_target(resp)
|
||||||
|
previous_fragment = urlparse(req.url).fragment
|
||||||
while url:
|
while url:
|
||||||
prepared_request = req.copy()
|
prepared_request = req.copy()
|
||||||
|
|
||||||
|
@ -147,8 +147,12 @@ class SessionRedirectMixin(object):
|
||||||
parsed_rurl = urlparse(resp.url)
|
parsed_rurl = urlparse(resp.url)
|
||||||
url = '%s:%s' % (to_native_string(parsed_rurl.scheme), url)
|
url = '%s:%s' % (to_native_string(parsed_rurl.scheme), url)
|
||||||
|
|
||||||
# The scheme should be lower case...
|
# Normalize url case and attach previous fragment if needed (RFC 7231 7.1.2)
|
||||||
parsed = urlparse(url)
|
parsed = urlparse(url)
|
||||||
|
if parsed.fragment == '' and previous_fragment:
|
||||||
|
parsed = parsed._replace(fragment=previous_fragment)
|
||||||
|
elif parsed.fragment:
|
||||||
|
previous_fragment = parsed.fragment
|
||||||
url = parsed.geturl()
|
url = parsed.geturl()
|
||||||
|
|
||||||
# Facilitate relative 'location' headers, as allowed by RFC 7231.
|
# Facilitate relative 'location' headers, as allowed by RFC 7231.
|
||||||
|
@ -696,7 +700,7 @@ class Session(SessionRedirectMixin):
|
||||||
"""
|
"""
|
||||||
for (prefix, adapter) in self.adapters.items():
|
for (prefix, adapter) in self.adapters.items():
|
||||||
|
|
||||||
if url.lower().startswith(prefix):
|
if url.lower().startswith(prefix.lower()):
|
||||||
return adapter
|
return adapter
|
||||||
|
|
||||||
# Nothing matches :-/
|
# Nothing matches :-/
|
||||||
|
|
|
@ -1,5 +1,22 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
The ``codes`` object defines a mapping from common names for HTTP statuses
|
||||||
|
to their numerical codes, accessible either as attributes or as dictionary
|
||||||
|
items.
|
||||||
|
|
||||||
|
>>> requests.codes['temporary_redirect']
|
||||||
|
307
|
||||||
|
>>> requests.codes.teapot
|
||||||
|
418
|
||||||
|
>>> requests.codes['\o/']
|
||||||
|
200
|
||||||
|
|
||||||
|
Some codes have multiple names, and both upper- and lower-case versions of
|
||||||
|
the names are allowed. For example, ``codes.ok``, ``codes.OK``, and
|
||||||
|
``codes.okay`` all correspond to the HTTP status code 200.
|
||||||
|
"""
|
||||||
|
|
||||||
from .structures import LookupDict
|
from .structures import LookupDict
|
||||||
|
|
||||||
_codes = {
|
_codes = {
|
||||||
|
@ -84,8 +101,20 @@ _codes = {
|
||||||
|
|
||||||
codes = LookupDict(name='status_codes')
|
codes = LookupDict(name='status_codes')
|
||||||
|
|
||||||
for code, titles in _codes.items():
|
def _init():
|
||||||
for title in titles:
|
for code, titles in _codes.items():
|
||||||
setattr(codes, title, code)
|
for title in titles:
|
||||||
if not title.startswith(('\\', '/')):
|
setattr(codes, title, code)
|
||||||
setattr(codes, title.upper(), code)
|
if not title.startswith(('\\', '/')):
|
||||||
|
setattr(codes, title.upper(), code)
|
||||||
|
|
||||||
|
def doc(code):
|
||||||
|
names = ', '.join('``%s``' % n for n in _codes[code])
|
||||||
|
return '* %d: %s' % (code, names)
|
||||||
|
|
||||||
|
global __doc__
|
||||||
|
__doc__ = (__doc__ + '\n' +
|
||||||
|
'\n'.join(doc(code) for code in sorted(_codes))
|
||||||
|
if __doc__ is not None else None)
|
||||||
|
|
||||||
|
_init()
|
||||||
|
|
|
@ -7,16 +7,14 @@ requests.structures
|
||||||
Data structures that power Requests.
|
Data structures that power Requests.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import collections
|
from .compat import OrderedDict, Mapping, MutableMapping
|
||||||
|
|
||||||
from .compat import OrderedDict
|
|
||||||
|
|
||||||
|
|
||||||
class CaseInsensitiveDict(collections.MutableMapping):
|
class CaseInsensitiveDict(MutableMapping):
|
||||||
"""A case-insensitive ``dict``-like object.
|
"""A case-insensitive ``dict``-like object.
|
||||||
|
|
||||||
Implements all methods and operations of
|
Implements all methods and operations of
|
||||||
``collections.MutableMapping`` as well as dict's ``copy``. Also
|
``MutableMapping`` as well as dict's ``copy``. Also
|
||||||
provides ``lower_items``.
|
provides ``lower_items``.
|
||||||
|
|
||||||
All keys are expected to be strings. The structure remembers the
|
All keys are expected to be strings. The structure remembers the
|
||||||
|
@ -71,7 +69,7 @@ class CaseInsensitiveDict(collections.MutableMapping):
|
||||||
)
|
)
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if isinstance(other, collections.Mapping):
|
if isinstance(other, Mapping):
|
||||||
other = CaseInsensitiveDict(other)
|
other = CaseInsensitiveDict(other)
|
||||||
else:
|
else:
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
|
|
|
@ -8,17 +8,17 @@ This module provides utility functions that are used within Requests
|
||||||
that are also useful for external consumption.
|
that are also useful for external consumption.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import cgi
|
|
||||||
import codecs
|
import codecs
|
||||||
import collections
|
|
||||||
import contextlib
|
import contextlib
|
||||||
import io
|
import io
|
||||||
import os
|
import os
|
||||||
import platform
|
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
import struct
|
import struct
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
import warnings
|
import warnings
|
||||||
|
import zipfile
|
||||||
|
|
||||||
from .__version__ import __version__
|
from .__version__ import __version__
|
||||||
from . import certs
|
from . import certs
|
||||||
|
@ -28,7 +28,7 @@ from .compat import parse_http_list as _parse_list_header
|
||||||
from .compat import (
|
from .compat import (
|
||||||
quote, urlparse, bytes, str, OrderedDict, unquote, getproxies,
|
quote, urlparse, bytes, str, OrderedDict, unquote, getproxies,
|
||||||
proxy_bypass, urlunparse, basestring, integer_types, is_py3,
|
proxy_bypass, urlunparse, basestring, integer_types, is_py3,
|
||||||
proxy_bypass_environment, getproxies_environment)
|
proxy_bypass_environment, getproxies_environment, Mapping)
|
||||||
from .cookies import cookiejar_from_dict
|
from .cookies import cookiejar_from_dict
|
||||||
from .structures import CaseInsensitiveDict
|
from .structures import CaseInsensitiveDict
|
||||||
from .exceptions import (
|
from .exceptions import (
|
||||||
|
@ -39,19 +39,25 @@ NETRC_FILES = ('.netrc', '_netrc')
|
||||||
DEFAULT_CA_BUNDLE_PATH = certs.where()
|
DEFAULT_CA_BUNDLE_PATH = certs.where()
|
||||||
|
|
||||||
|
|
||||||
if platform.system() == 'Windows':
|
if sys.platform == 'win32':
|
||||||
# provide a proxy_bypass version on Windows without DNS lookups
|
# provide a proxy_bypass version on Windows without DNS lookups
|
||||||
|
|
||||||
def proxy_bypass_registry(host):
|
def proxy_bypass_registry(host):
|
||||||
if is_py3:
|
try:
|
||||||
import winreg
|
if is_py3:
|
||||||
else:
|
import winreg
|
||||||
import _winreg as winreg
|
else:
|
||||||
|
import _winreg as winreg
|
||||||
|
except ImportError:
|
||||||
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
|
internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
|
||||||
r'Software\Microsoft\Windows\CurrentVersion\Internet Settings')
|
r'Software\Microsoft\Windows\CurrentVersion\Internet Settings')
|
||||||
proxyEnable = winreg.QueryValueEx(internetSettings,
|
# ProxyEnable could be REG_SZ or REG_DWORD, normalizing it
|
||||||
'ProxyEnable')[0]
|
proxyEnable = int(winreg.QueryValueEx(internetSettings,
|
||||||
|
'ProxyEnable')[0])
|
||||||
|
# ProxyOverride is almost always a string
|
||||||
proxyOverride = winreg.QueryValueEx(internetSettings,
|
proxyOverride = winreg.QueryValueEx(internetSettings,
|
||||||
'ProxyOverride')[0]
|
'ProxyOverride')[0]
|
||||||
except OSError:
|
except OSError:
|
||||||
|
@ -216,6 +222,38 @@ def guess_filename(obj):
|
||||||
return os.path.basename(name)
|
return os.path.basename(name)
|
||||||
|
|
||||||
|
|
||||||
|
def extract_zipped_paths(path):
|
||||||
|
"""Replace nonexistent paths that look like they refer to a member of a zip
|
||||||
|
archive with the location of an extracted copy of the target, or else
|
||||||
|
just return the provided path unchanged.
|
||||||
|
"""
|
||||||
|
if os.path.exists(path):
|
||||||
|
# this is already a valid path, no need to do anything further
|
||||||
|
return path
|
||||||
|
|
||||||
|
# find the first valid part of the provided path and treat that as a zip archive
|
||||||
|
# assume the rest of the path is the name of a member in the archive
|
||||||
|
archive, member = os.path.split(path)
|
||||||
|
while archive and not os.path.exists(archive):
|
||||||
|
archive, prefix = os.path.split(archive)
|
||||||
|
member = '/'.join([prefix, member])
|
||||||
|
|
||||||
|
if not zipfile.is_zipfile(archive):
|
||||||
|
return path
|
||||||
|
|
||||||
|
zip_file = zipfile.ZipFile(archive)
|
||||||
|
if member not in zip_file.namelist():
|
||||||
|
return path
|
||||||
|
|
||||||
|
# we have a valid zip archive and a valid member of that archive
|
||||||
|
tmp = tempfile.gettempdir()
|
||||||
|
extracted_path = os.path.join(tmp, *member.split('/'))
|
||||||
|
if not os.path.exists(extracted_path):
|
||||||
|
extracted_path = zip_file.extract(member, path=tmp)
|
||||||
|
|
||||||
|
return extracted_path
|
||||||
|
|
||||||
|
|
||||||
def from_key_val_list(value):
|
def from_key_val_list(value):
|
||||||
"""Take an object and test to see if it can be represented as a
|
"""Take an object and test to see if it can be represented as a
|
||||||
dictionary. Unless it can not be represented as such, return an
|
dictionary. Unless it can not be represented as such, return an
|
||||||
|
@ -262,7 +300,7 @@ def to_key_val_list(value):
|
||||||
if isinstance(value, (str, bytes, bool, int)):
|
if isinstance(value, (str, bytes, bool, int)):
|
||||||
raise ValueError('cannot encode objects that are not 2-tuples')
|
raise ValueError('cannot encode objects that are not 2-tuples')
|
||||||
|
|
||||||
if isinstance(value, collections.Mapping):
|
if isinstance(value, Mapping):
|
||||||
value = value.items()
|
value = value.items()
|
||||||
|
|
||||||
return list(value)
|
return list(value)
|
||||||
|
@ -407,6 +445,31 @@ def get_encodings_from_content(content):
|
||||||
xml_re.findall(content))
|
xml_re.findall(content))
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_content_type_header(header):
|
||||||
|
"""Returns content type and parameters from given header
|
||||||
|
|
||||||
|
:param header: string
|
||||||
|
:return: tuple containing content type and dictionary of
|
||||||
|
parameters
|
||||||
|
"""
|
||||||
|
|
||||||
|
tokens = header.split(';')
|
||||||
|
content_type, params = tokens[0].strip(), tokens[1:]
|
||||||
|
params_dict = {}
|
||||||
|
items_to_strip = "\"' "
|
||||||
|
|
||||||
|
for param in params:
|
||||||
|
param = param.strip()
|
||||||
|
if param:
|
||||||
|
key, value = param, True
|
||||||
|
index_of_equals = param.find("=")
|
||||||
|
if index_of_equals != -1:
|
||||||
|
key = param[:index_of_equals].strip(items_to_strip)
|
||||||
|
value = param[index_of_equals + 1:].strip(items_to_strip)
|
||||||
|
params_dict[key] = value
|
||||||
|
return content_type, params_dict
|
||||||
|
|
||||||
|
|
||||||
def get_encoding_from_headers(headers):
|
def get_encoding_from_headers(headers):
|
||||||
"""Returns encodings from given HTTP Header Dict.
|
"""Returns encodings from given HTTP Header Dict.
|
||||||
|
|
||||||
|
@ -419,7 +482,7 @@ def get_encoding_from_headers(headers):
|
||||||
if not content_type:
|
if not content_type:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
content_type, params = cgi.parse_header(content_type)
|
content_type, params = _parse_content_type_header(content_type)
|
||||||
|
|
||||||
if 'charset' in params:
|
if 'charset' in params:
|
||||||
return params['charset'].strip("'\"")
|
return params['charset'].strip("'\"")
|
||||||
|
@ -632,6 +695,8 @@ def should_bypass_proxies(url, no_proxy):
|
||||||
|
|
||||||
:rtype: bool
|
:rtype: bool
|
||||||
"""
|
"""
|
||||||
|
# Prioritize lowercase environment variables over uppercase
|
||||||
|
# to keep a consistent behaviour with other http projects (curl, wget).
|
||||||
get_proxy = lambda k: os.environ.get(k) or os.environ.get(k.upper())
|
get_proxy = lambda k: os.environ.get(k) or os.environ.get(k.upper())
|
||||||
|
|
||||||
# First check whether no_proxy is defined. If it is, check that the URL
|
# First check whether no_proxy is defined. If it is, check that the URL
|
||||||
|
@ -639,28 +704,31 @@ def should_bypass_proxies(url, no_proxy):
|
||||||
no_proxy_arg = no_proxy
|
no_proxy_arg = no_proxy
|
||||||
if no_proxy is None:
|
if no_proxy is None:
|
||||||
no_proxy = get_proxy('no_proxy')
|
no_proxy = get_proxy('no_proxy')
|
||||||
netloc = urlparse(url).netloc
|
parsed = urlparse(url)
|
||||||
|
|
||||||
if no_proxy:
|
if no_proxy:
|
||||||
# We need to check whether we match here. We need to see if we match
|
# We need to check whether we match here. We need to see if we match
|
||||||
# the end of the netloc, both with and without the port.
|
# the end of the hostname, both with and without the port.
|
||||||
no_proxy = (
|
no_proxy = (
|
||||||
host for host in no_proxy.replace(' ', '').split(',') if host
|
host for host in no_proxy.replace(' ', '').split(',') if host
|
||||||
)
|
)
|
||||||
|
|
||||||
ip = netloc.split(':')[0]
|
if is_ipv4_address(parsed.hostname):
|
||||||
if is_ipv4_address(ip):
|
|
||||||
for proxy_ip in no_proxy:
|
for proxy_ip in no_proxy:
|
||||||
if is_valid_cidr(proxy_ip):
|
if is_valid_cidr(proxy_ip):
|
||||||
if address_in_network(ip, proxy_ip):
|
if address_in_network(parsed.hostname, proxy_ip):
|
||||||
return True
|
return True
|
||||||
elif ip == proxy_ip:
|
elif parsed.hostname == proxy_ip:
|
||||||
# If no_proxy ip was defined in plain IP notation instead of cidr notation &
|
# If no_proxy ip was defined in plain IP notation instead of cidr notation &
|
||||||
# matches the IP of the index
|
# matches the IP of the index
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
|
host_with_port = parsed.hostname
|
||||||
|
if parsed.port:
|
||||||
|
host_with_port += ':{0}'.format(parsed.port)
|
||||||
|
|
||||||
for host in no_proxy:
|
for host in no_proxy:
|
||||||
if netloc.endswith(host) or netloc.split(':')[0].endswith(host):
|
if parsed.hostname.endswith(host) or host_with_port.endswith(host):
|
||||||
# The URL does match something in no_proxy, so we don't want
|
# The URL does match something in no_proxy, so we don't want
|
||||||
# to apply the proxies on this URL.
|
# to apply the proxies on this URL.
|
||||||
return True
|
return True
|
||||||
|
@ -673,7 +741,7 @@ def should_bypass_proxies(url, no_proxy):
|
||||||
# legitimate problems.
|
# legitimate problems.
|
||||||
with set_environ('no_proxy', no_proxy_arg):
|
with set_environ('no_proxy', no_proxy_arg):
|
||||||
try:
|
try:
|
||||||
bypass = proxy_bypass(netloc)
|
bypass = proxy_bypass(parsed.hostname)
|
||||||
except (TypeError, socket.gaierror):
|
except (TypeError, socket.gaierror):
|
||||||
bypass = False
|
bypass = False
|
||||||
|
|
||||||
|
@ -743,7 +811,7 @@ def default_headers():
|
||||||
|
|
||||||
|
|
||||||
def parse_header_links(value):
|
def parse_header_links(value):
|
||||||
"""Return a dict of parsed link headers proxies.
|
"""Return a list of parsed link headers proxies.
|
||||||
|
|
||||||
i.e. Link: <http:/.../front.jpeg>; rel=front; type="image/jpeg",<http://.../back.jpeg>; rel=back;type="image/jpeg"
|
i.e. Link: <http:/.../front.jpeg>; rel=front; type="image/jpeg",<http://.../back.jpeg>; rel=back;type="image/jpeg"
|
||||||
|
|
||||||
|
@ -754,6 +822,10 @@ def parse_header_links(value):
|
||||||
|
|
||||||
replace_chars = ' \'"'
|
replace_chars = ' \'"'
|
||||||
|
|
||||||
|
value = value.strip(replace_chars)
|
||||||
|
if not value:
|
||||||
|
return links
|
||||||
|
|
||||||
for val in re.split(', *<', value):
|
for val in re.split(', *<', value):
|
||||||
try:
|
try:
|
||||||
url, params = val.split(';', 1)
|
url, params = val.split(';', 1)
|
||||||
|
|
|
@ -13,7 +13,7 @@ packaging==17.1
|
||||||
pyparsing==2.2.0
|
pyparsing==2.2.0
|
||||||
pytoml==0.1.16
|
pytoml==0.1.16
|
||||||
retrying==1.3.3
|
retrying==1.3.3
|
||||||
requests==2.18.4
|
requests==2.19.1
|
||||||
chardet==3.0.4
|
chardet==3.0.4
|
||||||
idna==2.7
|
idna==2.7
|
||||||
urllib3==1.23
|
urllib3==1.23
|
||||||
|
|
|
@ -24,13 +24,17 @@ diff --git a/src/pip/_vendor/requests/__init__.py b/src/pip/_vendor/requests/__i
|
||||||
index 9c3b769..36a4ef40 100644
|
index 9c3b769..36a4ef40 100644
|
||||||
--- a/src/pip/_vendor/requests/__init__.py
|
--- a/src/pip/_vendor/requests/__init__.py
|
||||||
+++ b/src/pip/_vendor/requests/__init__.py
|
+++ b/src/pip/_vendor/requests/__init__.py
|
||||||
@@ -80,10 +80,12 @@ except (AssertionError, ValueError):
|
@@ -80,13 +80,15 @@ except (AssertionError, ValueError):
|
||||||
RequestsDependencyWarning)
|
RequestsDependencyWarning)
|
||||||
|
|
||||||
# Attempt to enable urllib3's SNI support, if possible
|
# Attempt to enable urllib3's SNI support, if possible
|
||||||
-try:
|
-try:
|
||||||
- from pip._vendor.urllib3.contrib import pyopenssl
|
- from pip._vendor.urllib3.contrib import pyopenssl
|
||||||
- pyopenssl.inject_into_urllib3()
|
- pyopenssl.inject_into_urllib3()
|
||||||
|
-
|
||||||
|
- # Check cryptography version
|
||||||
|
- from cryptography import __version__ as cryptography_version
|
||||||
|
- _check_cryptography(cryptography_version)
|
||||||
-except ImportError:
|
-except ImportError:
|
||||||
- pass
|
- pass
|
||||||
+from pip._internal.compat import WINDOWS
|
+from pip._internal.compat import WINDOWS
|
||||||
|
@ -38,6 +42,10 @@ index 9c3b769..36a4ef40 100644
|
||||||
+ try:
|
+ try:
|
||||||
+ from pip._vendor.urllib3.contrib import pyopenssl
|
+ from pip._vendor.urllib3.contrib import pyopenssl
|
||||||
+ pyopenssl.inject_into_urllib3()
|
+ pyopenssl.inject_into_urllib3()
|
||||||
|
+
|
||||||
|
+ # Check cryptography version
|
||||||
|
+ from cryptography import __version__ as cryptography_version
|
||||||
|
+ _check_cryptography(cryptography_version)
|
||||||
+ except ImportError:
|
+ except ImportError:
|
||||||
+ pass
|
+ pass
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue