Skip to content

Commit 0fb0e3b

Browse files
illia-vuranusjr
andauthored
Upgrade vendored requests to 2.26.0 (#10174)
Co-authored-by: Tzu-ping Chung <[email protected]>
1 parent c5abdda commit 0fb0e3b

File tree

11 files changed

+152
-36
lines changed

11 files changed

+152
-36
lines changed

news/requests.vendor.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Upgrade requests to 2.26.0.

src/pip/_vendor/requests/__init__.py

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,17 @@
4141
"""
4242

4343
from pip._vendor import urllib3
44-
from pip._vendor import chardet
4544
import warnings
4645
from .exceptions import RequestsDependencyWarning
4746

47+
charset_normalizer_version = None
4848

49-
def check_compatibility(urllib3_version, chardet_version):
49+
try:
50+
from pip._vendor.chardet import __version__ as chardet_version
51+
except ImportError:
52+
chardet_version = None
53+
54+
def check_compatibility(urllib3_version, chardet_version, charset_normalizer_version):
5055
urllib3_version = urllib3_version.split('.')
5156
assert urllib3_version != ['dev'] # Verify urllib3 isn't installed from git.
5257

@@ -62,12 +67,19 @@ def check_compatibility(urllib3_version, chardet_version):
6267
assert minor >= 21
6368
assert minor <= 26
6469

65-
# Check chardet for compatibility.
66-
major, minor, patch = chardet_version.split('.')[:3]
67-
major, minor, patch = int(major), int(minor), int(patch)
68-
# chardet >= 3.0.2, < 5.0.0
69-
assert (3, 0, 2) <= (major, minor, patch) < (5, 0, 0)
70-
70+
# Check charset_normalizer for compatibility.
71+
if chardet_version:
72+
major, minor, patch = chardet_version.split('.')[:3]
73+
major, minor, patch = int(major), int(minor), int(patch)
74+
# chardet_version >= 3.0.2, < 5.0.0
75+
assert (3, 0, 2) <= (major, minor, patch) < (5, 0, 0)
76+
elif charset_normalizer_version:
77+
major, minor, patch = charset_normalizer_version.split('.')[:3]
78+
major, minor, patch = int(major), int(minor), int(patch)
79+
# charset_normalizer >= 2.0.0 < 3.0.0
80+
assert (2, 0, 0) <= (major, minor, patch) < (3, 0, 0)
81+
else:
82+
raise Exception("You need either charset_normalizer or chardet installed")
7183

7284
def _check_cryptography(cryptography_version):
7385
# cryptography < 1.3.4
@@ -82,10 +94,10 @@ def _check_cryptography(cryptography_version):
8294

8395
# Check imported dependencies for compatibility.
8496
try:
85-
check_compatibility(urllib3.__version__, chardet.__version__)
97+
check_compatibility(urllib3.__version__, chardet_version, charset_normalizer_version)
8698
except (AssertionError, ValueError):
87-
warnings.warn("urllib3 ({}) or chardet ({}) doesn't match a supported "
88-
"version!".format(urllib3.__version__, chardet.__version__),
99+
warnings.warn("urllib3 ({}) or chardet ({})/charset_normalizer ({}) doesn't match a supported "
100+
"version!".format(urllib3.__version__, chardet_version, charset_normalizer_version),
89101
RequestsDependencyWarning)
90102

91103
# Attempt to enable urllib3's fallback for SNI support

src/pip/_vendor/requests/__version__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
__title__ = 'requests'
66
__description__ = 'Python HTTP for Humans.'
77
__url__ = 'https://requests.readthedocs.io'
8-
__version__ = '2.25.1'
9-
__build__ = 0x022501
8+
__version__ = '2.26.0'
9+
__build__ = 0x022600
1010
__author__ = 'Kenneth Reitz'
1111
__author_email__ = '[email protected]'
1212
__license__ = 'Apache 2.0'

src/pip/_vendor/requests/api.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ def get(url, params=None, **kwargs):
7272
:rtype: requests.Response
7373
"""
7474

75-
kwargs.setdefault('allow_redirects', True)
7675
return request('get', url, params=params, **kwargs)
7776

7877

@@ -85,7 +84,6 @@ def options(url, **kwargs):
8584
:rtype: requests.Response
8685
"""
8786

88-
kwargs.setdefault('allow_redirects', True)
8987
return request('options', url, **kwargs)
9088

9189

src/pip/_vendor/requests/exceptions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ def __init__(self, *args, **kwargs):
2525
super(RequestException, self).__init__(*args, **kwargs)
2626

2727

28+
class InvalidJSONError(RequestException):
29+
"""A JSON error occurred."""
30+
31+
2832
class HTTPError(RequestException):
2933
"""An HTTP error occurred."""
3034

src/pip/_vendor/requests/help.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,16 @@
88

99
from pip._vendor import idna
1010
from pip._vendor import urllib3
11-
from pip._vendor import chardet
1211

1312
from . import __version__ as requests_version
1413

14+
charset_normalizer = None
15+
16+
try:
17+
from pip._vendor import chardet
18+
except ImportError:
19+
chardet = None
20+
1521
try:
1622
from pip._vendor.urllib3.contrib import pyopenssl
1723
except ImportError:
@@ -71,7 +77,12 @@ def info():
7177

7278
implementation_info = _implementation()
7379
urllib3_info = {'version': urllib3.__version__}
74-
chardet_info = {'version': chardet.__version__}
80+
charset_normalizer_info = {'version': None}
81+
chardet_info = {'version': None}
82+
if charset_normalizer:
83+
charset_normalizer_info = {'version': charset_normalizer.__version__}
84+
if chardet:
85+
chardet_info = {'version': chardet.__version__}
7586

7687
pyopenssl_info = {
7788
'version': None,
@@ -99,9 +110,11 @@ def info():
99110
'implementation': implementation_info,
100111
'system_ssl': system_ssl_info,
101112
'using_pyopenssl': pyopenssl is not None,
113+
'using_charset_normalizer': chardet is None,
102114
'pyOpenSSL': pyopenssl_info,
103115
'urllib3': urllib3_info,
104116
'chardet': chardet_info,
117+
'charset_normalizer': charset_normalizer_info,
105118
'cryptography': cryptography_info,
106119
'idna': idna_info,
107120
'requests': {

src/pip/_vendor/requests/models.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
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)
32+
ContentDecodingError, ConnectionError, StreamConsumedError, InvalidJSONError)
3333
from ._internal_utils import to_native_string, unicode_is_ascii
3434
from .utils import (
3535
guess_filename, get_auth_from_url, requote_uri,
@@ -466,7 +466,12 @@ def prepare_body(self, data, files, json=None):
466466
# urllib3 requires a bytes-like body. Python 2's json.dumps
467467
# provides this natively, but Python 3 gives a Unicode string.
468468
content_type = 'application/json'
469-
body = complexjson.dumps(json)
469+
470+
try:
471+
body = complexjson.dumps(json, allow_nan=False)
472+
except ValueError as ve:
473+
raise InvalidJSONError(ve, request=self)
474+
470475
if not isinstance(body, bytes):
471476
body = body.encode('utf-8')
472477

@@ -726,7 +731,7 @@ def next(self):
726731

727732
@property
728733
def apparent_encoding(self):
729-
"""The apparent encoding, provided by the chardet library."""
734+
"""The apparent encoding, provided by the charset_normalizer or chardet libraries."""
730735
return chardet.detect(self.content)['encoding']
731736

732737
def iter_content(self, chunk_size=1, decode_unicode=False):
@@ -840,7 +845,7 @@ def text(self):
840845
"""Content of the response, in unicode.
841846
842847
If Response.encoding is None, encoding will be guessed using
843-
``chardet``.
848+
``charset_normalizer`` or ``chardet``.
844849
845850
The encoding of the response content is determined based solely on HTTP
846851
headers, following RFC 2616 to the letter. If you can take advantage of
@@ -877,13 +882,18 @@ def json(self, **kwargs):
877882
r"""Returns the json-encoded content of a response, if any.
878883
879884
:param \*\*kwargs: Optional arguments that ``json.loads`` takes.
880-
:raises ValueError: If the response body does not contain valid json.
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.
881891
"""
882892

883893
if not self.encoding and self.content and len(self.content) > 3:
884894
# No encoding set. JSON RFC 4627 section 3 states we should expect
885895
# UTF-8, -16 or -32. Detect which one to use; If the detection or
886-
# decoding fails, fall back to `self.text` (using chardet to make
896+
# decoding fails, fall back to `self.text` (using charset_normalizer to make
887897
# a best guess).
888898
encoding = guess_json_utf(self.content)
889899
if encoding is not None:

src/pip/_vendor/requests/sessions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ def send(self, request, **kwargs):
633633
kwargs.setdefault('stream', self.stream)
634634
kwargs.setdefault('verify', self.verify)
635635
kwargs.setdefault('cert', self.cert)
636-
kwargs.setdefault('proxies', self.proxies)
636+
kwargs.setdefault('proxies', self.rebuild_proxies(request, self.proxies))
637637

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

src/pip/_vendor/requests/utils.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import warnings
2121
import zipfile
2222
from collections import OrderedDict
23+
from pip._vendor.urllib3.util import make_headers
2324

2425
from .__version__ import __version__
2526
from . import certs
@@ -41,6 +42,11 @@
4142

4243
DEFAULT_PORTS = {'http': 80, 'https': 443}
4344

45+
# Ensure that ', ' is used to preserve previous delimiter behavior.
46+
DEFAULT_ACCEPT_ENCODING = ", ".join(
47+
re.split(r",\s*", make_headers(accept_encoding=True)["accept-encoding"])
48+
)
49+
4450

4551
if sys.platform == 'win32':
4652
# provide a proxy_bypass version on Windows without DNS lookups
@@ -256,13 +262,28 @@ def extract_zipped_paths(path):
256262

257263
# we have a valid zip archive and a valid member of that archive
258264
tmp = tempfile.gettempdir()
259-
extracted_path = os.path.join(tmp, *member.split('/'))
265+
extracted_path = os.path.join(tmp, member.split('/')[-1])
260266
if not os.path.exists(extracted_path):
261-
extracted_path = zip_file.extract(member, path=tmp)
262-
267+
# use read + write to avoid the creating nested folders, we only want the file, avoids mkdir racing condition
268+
with atomic_open(extracted_path) as file_handler:
269+
file_handler.write(zip_file.read(member))
263270
return extracted_path
264271

265272

273+
@contextlib.contextmanager
274+
def atomic_open(filename):
275+
"""Write a file to the disk in an atomic fashion"""
276+
replacer = os.rename if sys.version_info[0] == 2 else os.replace
277+
tmp_descriptor, tmp_name = tempfile.mkstemp(dir=os.path.dirname(filename))
278+
try:
279+
with os.fdopen(tmp_descriptor, 'wb') as tmp_handler:
280+
yield tmp_handler
281+
replacer(tmp_name, filename)
282+
except BaseException:
283+
os.remove(tmp_name)
284+
raise
285+
286+
266287
def from_key_val_list(value):
267288
"""Take an object and test to see if it can be represented as a
268289
dictionary. Unless it can not be represented as such, return an
@@ -820,7 +841,7 @@ def default_headers():
820841
"""
821842
return CaseInsensitiveDict({
822843
'User-Agent': default_user_agent(),
823-
'Accept-Encoding': ', '.join(('gzip', 'deflate')),
844+
'Accept-Encoding': DEFAULT_ACCEPT_ENCODING,
824845
'Accept': '*/*',
825846
'Connection': 'keep-alive',
826847
})

src/pip/_vendor/vendor.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ packaging==21.0
99
pep517==0.11.0
1010
progress==1.5
1111
pyparsing==2.4.7
12-
requests==2.25.1
12+
requests==2.26.0
1313
certifi==2021.05.30
1414
chardet==4.0.0
1515
idna==3.2

0 commit comments

Comments
 (0)