Skip to content

Commit 60672c5

Browse files
committed
Upgrade Requests to 2.27.1
1 parent 7f8a684 commit 60672c5

File tree

11 files changed

+120
-49
lines changed

11 files changed

+120
-49
lines changed

news/requests.vendor.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add requests 2.27.1 as a vendored dependency.

src/pip/_vendor/requests/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ def _check_cryptography(cryptography_version):
141141
from .exceptions import (
142142
RequestException, Timeout, URLRequired,
143143
TooManyRedirects, HTTPError, ConnectionError,
144-
FileModeWarning, ConnectTimeout, ReadTimeout
144+
FileModeWarning, ConnectTimeout, ReadTimeout, JSONDecodeError
145145
)
146146

147147
# Set default logging handler to avoid "No handler found" warnings.

src/pip/_vendor/requests/__version__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
__title__ = 'requests'
66
__description__ = 'Python HTTP for Humans.'
77
__url__ = 'https://requests.readthedocs.io'
8-
__version__ = '2.26.0'
9-
__build__ = 0x022600
8+
__version__ = '2.27.1'
9+
__build__ = 0x022701
1010
__author__ = 'Kenneth Reitz'
1111
__author_email__ = '[email protected]'
1212
__license__ = 'Apache 2.0'
13-
__copyright__ = 'Copyright 2020 Kenneth Reitz'
13+
__copyright__ = 'Copyright 2022 Kenneth Reitz'
1414
__cake__ = u'\u2728 \U0001f370 \u2728'

src/pip/_vendor/requests/adapters.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from pip._vendor.urllib3.exceptions import ClosedPoolError
2020
from pip._vendor.urllib3.exceptions import ConnectTimeoutError
2121
from pip._vendor.urllib3.exceptions import HTTPError as _HTTPError
22+
from pip._vendor.urllib3.exceptions import InvalidHeader as _InvalidHeader
2223
from pip._vendor.urllib3.exceptions import MaxRetryError
2324
from pip._vendor.urllib3.exceptions import NewConnectionError
2425
from pip._vendor.urllib3.exceptions import ProxyError as _ProxyError
@@ -37,7 +38,7 @@
3738
from .cookies import extract_cookies_to_jar
3839
from .exceptions import (ConnectionError, ConnectTimeout, ReadTimeout, SSLError,
3940
ProxyError, RetryError, InvalidSchema, InvalidProxyURL,
40-
InvalidURL)
41+
InvalidURL, InvalidHeader)
4142
from .auth import _basic_auth_str
4243

4344
try:
@@ -457,9 +458,11 @@ def send(self, request, stream=False, timeout=None, verify=True, cert=None, prox
457458
low_conn = conn._get_conn(timeout=DEFAULT_POOL_TIMEOUT)
458459

459460
try:
461+
skip_host = 'Host' in request.headers
460462
low_conn.putrequest(request.method,
461463
url,
462-
skip_accept_encoding=True)
464+
skip_accept_encoding=True,
465+
skip_host=skip_host)
463466

464467
for header, value in request.headers.items():
465468
low_conn.putheader(header, value)
@@ -527,6 +530,8 @@ def send(self, request, stream=False, timeout=None, verify=True, cert=None, prox
527530
raise SSLError(e, request=request)
528531
elif isinstance(e, ReadTimeoutError):
529532
raise ReadTimeout(e, request=request)
533+
elif isinstance(e, _InvalidHeader):
534+
raise InvalidHeader(e, request=request)
530535
else:
531536
raise
532537

src/pip/_vendor/requests/compat.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,13 @@
5050
# Keep OrderedDict for backwards compatibility.
5151
from collections import Callable, Mapping, MutableMapping, OrderedDict
5252

53-
5453
builtin_str = str
5554
bytes = str
5655
str = unicode
5756
basestring = basestring
5857
numeric_types = (int, long, float)
5958
integer_types = (int, long)
59+
JSONDecodeError = ValueError
6060

6161
elif is_py3:
6262
from urllib.parse import urlparse, urlunparse, urljoin, urlsplit, urlencode, quote, unquote, quote_plus, unquote_plus, urldefrag
@@ -67,6 +67,7 @@
6767
# Keep OrderedDict for backwards compatibility.
6868
from collections import OrderedDict
6969
from collections.abc import Callable, Mapping, MutableMapping
70+
from json import JSONDecodeError
7071

7172
builtin_str = str
7273
str = str

src/pip/_vendor/requests/exceptions.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
"""
99
from pip._vendor.urllib3.exceptions import HTTPError as BaseHTTPError
1010

11+
from .compat import JSONDecodeError as CompatJSONDecodeError
12+
1113

1214
class RequestException(IOError):
1315
"""There was an ambiguous exception that occurred while handling your
@@ -29,6 +31,10 @@ class InvalidJSONError(RequestException):
2931
"""A JSON error occurred."""
3032

3133

34+
class JSONDecodeError(InvalidJSONError, CompatJSONDecodeError):
35+
"""Couldn't decode the text into json"""
36+
37+
3238
class HTTPError(RequestException):
3339
"""An HTTP error occurred."""
3440

@@ -74,11 +80,11 @@ class TooManyRedirects(RequestException):
7480

7581

7682
class MissingSchema(RequestException, ValueError):
77-
"""The URL schema (e.g. http or https) is missing."""
83+
"""The URL scheme (e.g. http or https) is missing."""
7884

7985

8086
class InvalidSchema(RequestException, ValueError):
81-
"""See defaults.py for valid schemas."""
87+
"""The URL scheme provided is either invalid or unsupported."""
8288

8389

8490
class InvalidURL(RequestException, ValueError):

src/pip/_vendor/requests/models.py

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929
from .cookies import cookiejar_from_dict, get_cookie_header, _copy_cookie_jar
3030
from .exceptions import (
3131
HTTPError, MissingSchema, InvalidURL, ChunkedEncodingError,
32-
ContentDecodingError, ConnectionError, StreamConsumedError, InvalidJSONError)
32+
ContentDecodingError, ConnectionError, StreamConsumedError,
33+
InvalidJSONError)
34+
from .exceptions import JSONDecodeError as RequestsJSONDecodeError
3335
from ._internal_utils import to_native_string, unicode_is_ascii
3436
from .utils import (
3537
guess_filename, get_auth_from_url, requote_uri,
@@ -38,7 +40,7 @@
3840
from .compat import (
3941
Callable, Mapping,
4042
cookielib, urlunparse, urlsplit, urlencode, str, bytes,
41-
is_py2, chardet, builtin_str, basestring)
43+
is_py2, chardet, builtin_str, basestring, JSONDecodeError)
4244
from .compat import json as complexjson
4345
from .status_codes import codes
4446

@@ -384,7 +386,7 @@ def prepare_url(self, url, params):
384386
raise InvalidURL(*e.args)
385387

386388
if not scheme:
387-
error = ("Invalid URL {0!r}: No schema supplied. Perhaps you meant http://{0}?")
389+
error = ("Invalid URL {0!r}: No scheme supplied. Perhaps you meant http://{0}?")
388390
error = error.format(to_native_string(url, 'utf8'))
389391

390392
raise MissingSchema(error)
@@ -401,7 +403,7 @@ def prepare_url(self, url, params):
401403
host = self._get_idna_encoded_host(host)
402404
except UnicodeError:
403405
raise InvalidURL('URL has an invalid label.')
404-
elif host.startswith(u'*'):
406+
elif host.startswith((u'*', u'.')):
405407
raise InvalidURL('URL has an invalid label.')
406408

407409
# Carefully reconstruct the network location
@@ -468,9 +470,9 @@ def prepare_body(self, data, files, json=None):
468470
content_type = 'application/json'
469471

470472
try:
471-
body = complexjson.dumps(json, allow_nan=False)
473+
body = complexjson.dumps(json, allow_nan=False)
472474
except ValueError as ve:
473-
raise InvalidJSONError(ve, request=self)
475+
raise InvalidJSONError(ve, request=self)
474476

475477
if not isinstance(body, bytes):
476478
body = body.encode('utf-8')
@@ -882,12 +884,8 @@ def json(self, **kwargs):
882884
r"""Returns the json-encoded content of a response, if any.
883885
884886
:param \*\*kwargs: Optional arguments that ``json.loads`` takes.
885-
:raises simplejson.JSONDecodeError: If the response body does not
886-
contain valid json and simplejson is installed.
887-
:raises json.JSONDecodeError: If the response body does not contain
888-
valid json and simplejson is not installed on Python 3.
889-
:raises ValueError: If the response body does not contain valid
890-
json and simplejson is not installed on Python 2.
887+
:raises requests.exceptions.JSONDecodeError: If the response body does not
888+
contain valid json.
891889
"""
892890

893891
if not self.encoding and self.content and len(self.content) > 3:
@@ -907,7 +905,16 @@ def json(self, **kwargs):
907905
# and the server didn't bother to tell us what codec *was*
908906
# used.
909907
pass
910-
return complexjson.loads(self.text, **kwargs)
908+
909+
try:
910+
return complexjson.loads(self.text, **kwargs)
911+
except JSONDecodeError as e:
912+
# Catch JSON-related errors and raise as requests.JSONDecodeError
913+
# This aliases json.JSONDecodeError and simplejson.JSONDecodeError
914+
if is_py2: # e is a ValueError
915+
raise RequestsJSONDecodeError(e.message)
916+
else:
917+
raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
911918

912919
@property
913920
def links(self):

src/pip/_vendor/requests/sessions.py

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
from .utils import (
3131
requote_uri, get_environ_proxies, get_netrc_auth, should_bypass_proxies,
32-
get_auth_from_url, rewind_body
32+
get_auth_from_url, rewind_body, resolve_proxies
3333
)
3434

3535
from .status_codes import codes
@@ -269,7 +269,6 @@ def rebuild_auth(self, prepared_request, response):
269269
if new_auth is not None:
270270
prepared_request.prepare_auth(new_auth)
271271

272-
273272
def rebuild_proxies(self, prepared_request, proxies):
274273
"""This method re-evaluates the proxy configuration by considering the
275274
environment variables. If we are redirected to a URL covered by
@@ -282,21 +281,9 @@ def rebuild_proxies(self, prepared_request, proxies):
282281
283282
:rtype: dict
284283
"""
285-
proxies = proxies if proxies is not None else {}
286284
headers = prepared_request.headers
287-
url = prepared_request.url
288-
scheme = urlparse(url).scheme
289-
new_proxies = proxies.copy()
290-
no_proxy = proxies.get('no_proxy')
291-
292-
bypass_proxy = should_bypass_proxies(url, no_proxy=no_proxy)
293-
if self.trust_env and not bypass_proxy:
294-
environ_proxies = get_environ_proxies(url, no_proxy=no_proxy)
295-
296-
proxy = environ_proxies.get(scheme, environ_proxies.get('all'))
297-
298-
if proxy:
299-
new_proxies.setdefault(scheme, proxy)
285+
scheme = urlparse(prepared_request.url).scheme
286+
new_proxies = resolve_proxies(prepared_request, proxies, self.trust_env)
300287

301288
if 'Proxy-Authorization' in headers:
302289
del headers['Proxy-Authorization']
@@ -633,7 +620,10 @@ def send(self, request, **kwargs):
633620
kwargs.setdefault('stream', self.stream)
634621
kwargs.setdefault('verify', self.verify)
635622
kwargs.setdefault('cert', self.cert)
636-
kwargs.setdefault('proxies', self.rebuild_proxies(request, self.proxies))
623+
if 'proxies' not in kwargs:
624+
kwargs['proxies'] = resolve_proxies(
625+
request, self.proxies, self.trust_env
626+
)
637627

638628
# It's possible that users might accidentally send a Request object.
639629
# Guard against that specific failure case.

src/pip/_vendor/requests/utils.py

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import zipfile
2222
from collections import OrderedDict
2323
from pip._vendor.urllib3.util import make_headers
24+
from pip._vendor.urllib3.util import parse_url
2425

2526
from .__version__ import __version__
2627
from . import certs
@@ -124,7 +125,10 @@ def super_len(o):
124125
elif hasattr(o, 'fileno'):
125126
try:
126127
fileno = o.fileno()
127-
except io.UnsupportedOperation:
128+
except (io.UnsupportedOperation, AttributeError):
129+
# AttributeError is a surprising exception, seeing as how we've just checked
130+
# that `hasattr(o, 'fileno')`. It happens for objects obtained via
131+
# `Tarfile.extractfile()`, per issue 5229.
128132
pass
129133
else:
130134
total_length = os.fstat(fileno).st_size
@@ -154,7 +158,7 @@ def super_len(o):
154158
current_position = total_length
155159
else:
156160
if hasattr(o, 'seek') and total_length is None:
157-
# StringIO and BytesIO have seek but no useable fileno
161+
# StringIO and BytesIO have seek but no usable fileno
158162
try:
159163
# seek to end of file
160164
o.seek(0, 2)
@@ -251,6 +255,10 @@ def extract_zipped_paths(path):
251255
archive, member = os.path.split(path)
252256
while archive and not os.path.exists(archive):
253257
archive, prefix = os.path.split(archive)
258+
if not prefix:
259+
# If we don't check for an empty prefix after the split (in other words, archive remains unchanged after the split),
260+
# we _can_ end up in an infinite loop on a rare corner case affecting a small number of users
261+
break
254262
member = '/'.join([prefix, member])
255263

256264
if not zipfile.is_zipfile(archive):
@@ -826,6 +834,33 @@ def select_proxy(url, proxies):
826834
return proxy
827835

828836

837+
def resolve_proxies(request, proxies, trust_env=True):
838+
"""This method takes proxy information from a request and configuration
839+
input to resolve a mapping of target proxies. This will consider settings
840+
such a NO_PROXY to strip proxy configurations.
841+
842+
:param request: Request or PreparedRequest
843+
:param proxies: A dictionary of schemes or schemes and hosts to proxy URLs
844+
:param trust_env: Boolean declaring whether to trust environment configs
845+
846+
:rtype: dict
847+
"""
848+
proxies = proxies if proxies is not None else {}
849+
url = request.url
850+
scheme = urlparse(url).scheme
851+
no_proxy = proxies.get('no_proxy')
852+
new_proxies = proxies.copy()
853+
854+
if trust_env and not should_bypass_proxies(url, no_proxy=no_proxy):
855+
environ_proxies = get_environ_proxies(url, no_proxy=no_proxy)
856+
857+
proxy = environ_proxies.get(scheme, environ_proxies.get('all'))
858+
859+
if proxy:
860+
new_proxies.setdefault(scheme, proxy)
861+
return new_proxies
862+
863+
829864
def default_user_agent(name="python-requests"):
830865
"""
831866
Return a string representing the default user agent.
@@ -928,15 +963,27 @@ def prepend_scheme_if_needed(url, new_scheme):
928963
929964
:rtype: str
930965
"""
931-
scheme, netloc, path, params, query, fragment = urlparse(url, new_scheme)
932-
933-
# urlparse is a finicky beast, and sometimes decides that there isn't a
934-
# netloc present. Assume that it's being over-cautious, and switch netloc
935-
# and path if urlparse decided there was no netloc.
966+
parsed = parse_url(url)
967+
scheme, auth, host, port, path, query, fragment = parsed
968+
969+
# A defect in urlparse determines that there isn't a netloc present in some
970+
# urls. We previously assumed parsing was overly cautious, and swapped the
971+
# netloc and path. Due to a lack of tests on the original defect, this is
972+
# maintained with parse_url for backwards compatibility.
973+
netloc = parsed.netloc
936974
if not netloc:
937975
netloc, path = path, netloc
938976

939-
return urlunparse((scheme, netloc, path, params, query, fragment))
977+
if auth:
978+
# parse_url doesn't provide the netloc with auth
979+
# so we'll add it ourselves.
980+
netloc = '@'.join([auth, netloc])
981+
if scheme is None:
982+
scheme = new_scheme
983+
if path is None:
984+
path = ''
985+
986+
return urlunparse((scheme, netloc, path, '', query, fragment))
940987

941988

942989
def get_auth_from_url(url):

src/pip/_vendor/vendor.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ pep517==0.12.0
99
platformdirs==2.4.0
1010
progress==1.6
1111
pyparsing==2.4.7
12-
requests==2.26.0
12+
requests==2.27.1
1313
certifi==2021.05.30
1414
chardet==4.0.0
1515
idna==3.2

0 commit comments

Comments
 (0)