Skip to content

Commit dec279e

Browse files
authored
Merge pull request #10815 from pradyunsg/vendoring-upgrade
2 parents bbcbfc6 + ab2ee1a commit dec279e

File tree

120 files changed

+13311
-14027
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

120 files changed

+13311
-14027
lines changed

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ include pyproject.toml
66

77
include src/pip/_vendor/README.rst
88
include src/pip/_vendor/vendor.txt
9+
include src/pip/_vendor/pyparsing/diagram/template.jinja2
910
recursive-include src/pip/_vendor *LICENSE*
1011
recursive-include src/pip/_vendor *COPYING*
1112

news/CacheControl.vendor.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Upgrade CacheControl to 0.12.10

news/certifi.vendor.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Upgrade certifi to 2021.10.8

news/distlib.vendor.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Upgrade distlib to 0.3.4

news/idna.vendor.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Upgrade idna to 3.3

news/msgpack.vendor.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Upgrade msgpack to 1.0.3

news/packaging.vendor.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Upgrade packaging to 21.3

news/platformdirs.vendor.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Upgrade platformdirs to 2.4.1

news/pygments.vendor.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Add pygments 2.10.0 as a vendored dependency.
1+
Add pygments 2.11.2 as a vendored dependency.

news/pyparsing.vendor.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Upgrade pyparsing to 3.0.7

news/rich-modifications.vendor.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Tree-trim unused portions of vendored rich, to reduce the distribution size.

news/rich.vendor.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Add rich 10.14.0 as a vendored dependency.
1+
Add rich 11.0.0 as a vendored dependency.

news/typing_extensions.vendor.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Add typing_extensions 3.10.0.2 as a vendored dependency.
1+
Add typing_extensions 4.0.1 as a vendored dependency.

src/pip/_internal/network/cache.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def get(self, key: str) -> Optional[bytes]:
5353
with open(path, "rb") as f:
5454
return f.read()
5555

56-
def set(self, key: str, value: bytes) -> None:
56+
def set(self, key: str, value: bytes, expires: Optional[int] = None) -> None:
5757
path = self._get_cache_path(key)
5858
with suppressed_cache_errors():
5959
ensure_dir(os.path.dirname(path))
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright 2015 Eric Larson
1+
Copyright 2012-2021 Eric Larson
22

33
Licensed under the Apache License, Version 2.0 (the "License");
44
you may not use this file except in compliance with the License.
@@ -8,8 +8,6 @@ You may obtain a copy of the License at
88

99
Unless required by applicable law or agreed to in writing, software
1010
distributed under the License is distributed on an "AS IS" BASIS,
11-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12-
implied.
13-
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1412
See the License for the specific language governing permissions and
1513
limitations under the License.
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
1+
# SPDX-FileCopyrightText: 2015 Eric Larson
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
15
"""CacheControl import Interface.
26
37
Make it easy to import from cachecontrol without long namespaces.
48
"""
59
__author__ = "Eric Larson"
610
__email__ = "[email protected]"
7-
__version__ = "0.12.6"
11+
__version__ = "0.12.10"
812

913
from .wrapper import CacheControl
1014
from .adapter import CacheControlAdapter
1115
from .controller import CacheController
16+
17+
import logging
18+
logging.getLogger(__name__).addHandler(logging.NullHandler())

src/pip/_vendor/cachecontrol/_cmd.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# SPDX-FileCopyrightText: 2015 Eric Larson
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
15
import logging
26

37
from pip._vendor import requests

src/pip/_vendor/cachecontrol/adapter.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
1+
# SPDX-FileCopyrightText: 2015 Eric Larson
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
15
import types
26
import functools
37
import zlib
48

59
from pip._vendor.requests.adapters import HTTPAdapter
610

7-
from .controller import CacheController
11+
from .controller import CacheController, PERMANENT_REDIRECT_STATUSES
812
from .cache import DictCache
913
from .filewrapper import CallbackFileWrapper
1014

1115

1216
class CacheControlAdapter(HTTPAdapter):
13-
invalidating_methods = {"PUT", "DELETE"}
17+
invalidating_methods = {"PUT", "PATCH", "DELETE"}
1418

1519
def __init__(
1620
self,
@@ -93,7 +97,7 @@ def build_response(
9397
response = cached_response
9498

9599
# We always cache the 301 responses
96-
elif response.status == 301:
100+
elif int(response.status) in PERMANENT_REDIRECT_STATUSES:
97101
self.controller.cache_response(request, response)
98102
else:
99103
# Wrap the response file with a wrapper that will cache the

src/pip/_vendor/cachecontrol/cache.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# SPDX-FileCopyrightText: 2015 Eric Larson
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
15
"""
26
The cache object API for implementing caches. The default is a thread
37
safe in-memory dictionary.
@@ -10,7 +14,7 @@ class BaseCache(object):
1014
def get(self, key):
1115
raise NotImplementedError()
1216

13-
def set(self, key, value):
17+
def set(self, key, value, expires=None):
1418
raise NotImplementedError()
1519

1620
def delete(self, key):
@@ -29,7 +33,7 @@ def __init__(self, init_dict=None):
2933
def get(self, key):
3034
return self.data.get(key, None)
3135

32-
def set(self, key, value):
36+
def set(self, key, value, expires=None):
3337
with self.lock:
3438
self.data.update({key: value})
3539

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
1+
# SPDX-FileCopyrightText: 2015 Eric Larson
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
15
from .file_cache import FileCache # noqa
26
from .redis_cache import RedisCache # noqa

src/pip/_vendor/cachecontrol/caches/file_cache.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# SPDX-FileCopyrightText: 2015 Eric Larson
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
15
import hashlib
26
import os
37
from textwrap import dedent
@@ -114,7 +118,7 @@ def get(self, key):
114118
except FileNotFoundError:
115119
return None
116120

117-
def set(self, key, value):
121+
def set(self, key, value, expires=None):
118122
name = self._fn(key)
119123

120124
# Make sure the directory exists

src/pip/_vendor/cachecontrol/caches/redis_cache.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# SPDX-FileCopyrightText: 2015 Eric Larson
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
15
from __future__ import division
26

37
from datetime import datetime

src/pip/_vendor/cachecontrol/compat.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# SPDX-FileCopyrightText: 2015 Eric Larson
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
15
try:
26
from urllib.parse import urljoin
37
except ImportError:
@@ -9,7 +13,6 @@
913
except ImportError:
1014
import pickle
1115

12-
1316
# Handle the case where the requests module has been patched to not have
1417
# urllib3 bundled as part of its source.
1518
try:

src/pip/_vendor/cachecontrol/controller.py

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# SPDX-FileCopyrightText: 2015 Eric Larson
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
15
"""
26
The httplib2 algorithms ported for use with requests.
37
"""
@@ -17,6 +21,8 @@
1721

1822
URI = re.compile(r"^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?")
1923

24+
PERMANENT_REDIRECT_STATUSES = (301, 308)
25+
2026

2127
def parse_uri(uri):
2228
"""Parses a URI using the regex given in Appendix B of RFC 3986.
@@ -37,7 +43,7 @@ def __init__(
3743
self.cache = DictCache() if cache is None else cache
3844
self.cache_etags = cache_etags
3945
self.serializer = serializer or Serializer()
40-
self.cacheable_status_codes = status_codes or (200, 203, 300, 301)
46+
self.cacheable_status_codes = status_codes or (200, 203, 300, 301, 308)
4147

4248
@classmethod
4349
def _urlnorm(cls, uri):
@@ -147,17 +153,18 @@ def cached_request(self, request):
147153
logger.warning("Cache entry deserialization failed, entry ignored")
148154
return False
149155

150-
# If we have a cached 301, return it immediately. We don't
151-
# need to test our response for other headers b/c it is
156+
# If we have a cached permanent redirect, return it immediately. We
157+
# don't need to test our response for other headers b/c it is
152158
# intrinsically "cacheable" as it is Permanent.
159+
#
153160
# See:
154161
# https://tools.ietf.org/html/rfc7231#section-6.4.2
155162
#
156163
# Client can try to refresh the value by repeating the request
157164
# with cache busting headers as usual (ie no-cache).
158-
if resp.status == 301:
165+
if int(resp.status) in PERMANENT_REDIRECT_STATUSES:
159166
msg = (
160-
'Returning cached "301 Moved Permanently" response '
167+
"Returning cached permanent redirect response "
161168
"(ignoring date and etag information)"
162169
)
163170
logger.debug(msg)
@@ -261,6 +268,11 @@ def cache_response(self, request, response, body=None, status_codes=None):
261268

262269
response_headers = CaseInsensitiveDict(response.headers)
263270

271+
if "date" in response_headers:
272+
date = calendar.timegm(parsedate_tz(response_headers["date"]))
273+
else:
274+
date = 0
275+
264276
# If we've been given a body, our response has a Content-Length, that
265277
# Content-Length is valid then we can check to see if the body we've
266278
# been given matches the expected size, and if it doesn't we'll just
@@ -304,35 +316,62 @@ def cache_response(self, request, response, body=None, status_codes=None):
304316

305317
# If we've been given an etag, then keep the response
306318
if self.cache_etags and "etag" in response_headers:
319+
expires_time = 0
320+
if response_headers.get("expires"):
321+
expires = parsedate_tz(response_headers["expires"])
322+
if expires is not None:
323+
expires_time = calendar.timegm(expires) - date
324+
325+
expires_time = max(expires_time, 14 * 86400)
326+
327+
logger.debug("etag object cached for {0} seconds".format(expires_time))
307328
logger.debug("Caching due to etag")
308329
self.cache.set(
309-
cache_url, self.serializer.dumps(request, response, body=body)
330+
cache_url,
331+
self.serializer.dumps(request, response, body),
332+
expires=expires_time,
310333
)
311334

312-
# Add to the cache any 301s. We do this before looking that
313-
# the Date headers.
314-
elif response.status == 301:
315-
logger.debug("Caching permanant redirect")
316-
self.cache.set(cache_url, self.serializer.dumps(request, response))
335+
# Add to the cache any permanent redirects. We do this before looking
336+
# that the Date headers.
337+
elif int(response.status) in PERMANENT_REDIRECT_STATUSES:
338+
logger.debug("Caching permanent redirect")
339+
self.cache.set(cache_url, self.serializer.dumps(request, response, b""))
317340

318341
# Add to the cache if the response headers demand it. If there
319342
# is no date header then we can't do anything about expiring
320343
# the cache.
321344
elif "date" in response_headers:
345+
date = calendar.timegm(parsedate_tz(response_headers["date"]))
322346
# cache when there is a max-age > 0
323347
if "max-age" in cc and cc["max-age"] > 0:
324348
logger.debug("Caching b/c date exists and max-age > 0")
349+
expires_time = cc["max-age"]
325350
self.cache.set(
326-
cache_url, self.serializer.dumps(request, response, body=body)
351+
cache_url,
352+
self.serializer.dumps(request, response, body),
353+
expires=expires_time,
327354
)
328355

329356
# If the request can expire, it means we should cache it
330357
# in the meantime.
331358
elif "expires" in response_headers:
332359
if response_headers["expires"]:
333-
logger.debug("Caching b/c of expires header")
360+
expires = parsedate_tz(response_headers["expires"])
361+
if expires is not None:
362+
expires_time = calendar.timegm(expires) - date
363+
else:
364+
expires_time = None
365+
366+
logger.debug(
367+
"Caching b/c of expires header. expires in {0} seconds".format(
368+
expires_time
369+
)
370+
)
334371
self.cache.set(
335-
cache_url, self.serializer.dumps(request, response, body=body)
372+
cache_url,
373+
self.serializer.dumps(request, response, body=body),
374+
expires=expires_time,
336375
)
337376

338377
def update_cached_response(self, request, response):

src/pip/_vendor/cachecontrol/filewrapper.py

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
from io import BytesIO
1+
# SPDX-FileCopyrightText: 2015 Eric Larson
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
from tempfile import NamedTemporaryFile
6+
import mmap
27

38

49
class CallbackFileWrapper(object):
@@ -11,10 +16,17 @@ class CallbackFileWrapper(object):
1116
1217
This class uses members with a double underscore (__) leading prefix so as
1318
not to accidentally shadow an attribute.
19+
20+
The data is stored in a temporary file until it is all available. As long
21+
as the temporary files directory is disk-based (sometimes it's a
22+
memory-backed-``tmpfs`` on Linux), data will be unloaded to disk if memory
23+
pressure is high. For small files the disk usually won't be used at all,
24+
it'll all be in the filesystem memory cache, so there should be no
25+
performance impact.
1426
"""
1527

1628
def __init__(self, fp, callback):
17-
self.__buf = BytesIO()
29+
self.__buf = NamedTemporaryFile("rb+", delete=True)
1830
self.__fp = fp
1931
self.__callback = callback
2032

@@ -49,7 +61,19 @@ def __is_fp_closed(self):
4961

5062
def _close(self):
5163
if self.__callback:
52-
self.__callback(self.__buf.getvalue())
64+
if self.__buf.tell() == 0:
65+
# Empty file:
66+
result = b""
67+
else:
68+
# Return the data without actually loading it into memory,
69+
# relying on Python's buffer API and mmap(). mmap() just gives
70+
# a view directly into the filesystem's memory cache, so it
71+
# doesn't result in duplicate memory use.
72+
self.__buf.seek(0, 0)
73+
result = memoryview(
74+
mmap.mmap(self.__buf.fileno(), 0, access=mmap.ACCESS_READ)
75+
)
76+
self.__callback(result)
5377

5478
# We assign this to None here, because otherwise we can get into
5579
# really tricky problems where the CPython interpreter dead locks
@@ -58,9 +82,16 @@ def _close(self):
5882
# and allows the garbage collector to do it's thing normally.
5983
self.__callback = None
6084

85+
# Closing the temporary file releases memory and frees disk space.
86+
# Important when caching big files.
87+
self.__buf.close()
88+
6189
def read(self, amt=None):
6290
data = self.__fp.read(amt)
63-
self.__buf.write(data)
91+
if data:
92+
# We may be dealing with b'', a sign that things are over:
93+
# it's passed e.g. after we've already closed self.__buf.
94+
self.__buf.write(data)
6495
if self.__is_fp_closed():
6596
self._close()
6697

0 commit comments

Comments
 (0)