Skip to content

Commit ea727e4

Browse files
authored
Merge pull request #12136 from jbylund/joe/bump_urllib3
Update vendored urllib3 from 1.26.15 to 1.26.16
2 parents c2b8082 + c5c8507 commit ea727e4

File tree

6 files changed

+189
-11
lines changed

6 files changed

+189
-11
lines changed

Diff for: news/urllib3.vendor.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Upgrade urllib3 to 1.26.16

Diff for: src/pip/_vendor/urllib3/_version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# This file is protected via CODEOWNERS
2-
__version__ = "1.26.15"
2+
__version__ = "1.26.16"

Diff for: src/pip/_vendor/urllib3/connectionpool.py

+30-8
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@
5050
from .util.url import _normalize_host as normalize_host
5151
from .util.url import get_host, parse_url
5252

53+
try: # Platform-specific: Python 3
54+
import weakref
55+
56+
weakref_finalize = weakref.finalize
57+
except AttributeError: # Platform-specific: Python 2
58+
from .packages.backports.weakref_finalize import weakref_finalize
59+
5360
xrange = six.moves.xrange
5461

5562
log = logging.getLogger(__name__)
@@ -220,6 +227,16 @@ def __init__(
220227
self.conn_kw["proxy"] = self.proxy
221228
self.conn_kw["proxy_config"] = self.proxy_config
222229

230+
# Do not pass 'self' as callback to 'finalize'.
231+
# Then the 'finalize' would keep an endless living (leak) to self.
232+
# By just passing a reference to the pool allows the garbage collector
233+
# to free self if nobody else has a reference to it.
234+
pool = self.pool
235+
236+
# Close all the HTTPConnections in the pool before the
237+
# HTTPConnectionPool object is garbage collected.
238+
weakref_finalize(self, _close_pool_connections, pool)
239+
223240
def _new_conn(self):
224241
"""
225242
Return a fresh :class:`HTTPConnection`.
@@ -489,14 +506,8 @@ def close(self):
489506
# Disable access to the pool
490507
old_pool, self.pool = self.pool, None
491508

492-
try:
493-
while True:
494-
conn = old_pool.get(block=False)
495-
if conn:
496-
conn.close()
497-
498-
except queue.Empty:
499-
pass # Done.
509+
# Close all the HTTPConnections in the pool.
510+
_close_pool_connections(old_pool)
500511

501512
def is_same_host(self, url):
502513
"""
@@ -1108,3 +1119,14 @@ def _normalize_host(host, scheme):
11081119
if host.startswith("[") and host.endswith("]"):
11091120
host = host[1:-1]
11101121
return host
1122+
1123+
1124+
def _close_pool_connections(pool):
1125+
"""Drains a queue of connections and closes each one."""
1126+
try:
1127+
while True:
1128+
conn = pool.get(block=False)
1129+
if conn:
1130+
conn.close()
1131+
except queue.Empty:
1132+
pass # Done.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
backports.weakref_finalize
4+
~~~~~~~~~~~~~~~~~~
5+
6+
Backports the Python 3 ``weakref.finalize`` method.
7+
"""
8+
from __future__ import absolute_import
9+
10+
import itertools
11+
import sys
12+
from weakref import ref
13+
14+
__all__ = ["weakref_finalize"]
15+
16+
17+
class weakref_finalize(object):
18+
"""Class for finalization of weakrefable objects
19+
finalize(obj, func, *args, **kwargs) returns a callable finalizer
20+
object which will be called when obj is garbage collected. The
21+
first time the finalizer is called it evaluates func(*arg, **kwargs)
22+
and returns the result. After this the finalizer is dead, and
23+
calling it just returns None.
24+
When the program exits any remaining finalizers for which the
25+
atexit attribute is true will be run in reverse order of creation.
26+
By default atexit is true.
27+
"""
28+
29+
# Finalizer objects don't have any state of their own. They are
30+
# just used as keys to lookup _Info objects in the registry. This
31+
# ensures that they cannot be part of a ref-cycle.
32+
33+
__slots__ = ()
34+
_registry = {}
35+
_shutdown = False
36+
_index_iter = itertools.count()
37+
_dirty = False
38+
_registered_with_atexit = False
39+
40+
class _Info(object):
41+
__slots__ = ("weakref", "func", "args", "kwargs", "atexit", "index")
42+
43+
def __init__(self, obj, func, *args, **kwargs):
44+
if not self._registered_with_atexit:
45+
# We may register the exit function more than once because
46+
# of a thread race, but that is harmless
47+
import atexit
48+
49+
atexit.register(self._exitfunc)
50+
weakref_finalize._registered_with_atexit = True
51+
info = self._Info()
52+
info.weakref = ref(obj, self)
53+
info.func = func
54+
info.args = args
55+
info.kwargs = kwargs or None
56+
info.atexit = True
57+
info.index = next(self._index_iter)
58+
self._registry[self] = info
59+
weakref_finalize._dirty = True
60+
61+
def __call__(self, _=None):
62+
"""If alive then mark as dead and return func(*args, **kwargs);
63+
otherwise return None"""
64+
info = self._registry.pop(self, None)
65+
if info and not self._shutdown:
66+
return info.func(*info.args, **(info.kwargs or {}))
67+
68+
def detach(self):
69+
"""If alive then mark as dead and return (obj, func, args, kwargs);
70+
otherwise return None"""
71+
info = self._registry.get(self)
72+
obj = info and info.weakref()
73+
if obj is not None and self._registry.pop(self, None):
74+
return (obj, info.func, info.args, info.kwargs or {})
75+
76+
def peek(self):
77+
"""If alive then return (obj, func, args, kwargs);
78+
otherwise return None"""
79+
info = self._registry.get(self)
80+
obj = info and info.weakref()
81+
if obj is not None:
82+
return (obj, info.func, info.args, info.kwargs or {})
83+
84+
@property
85+
def alive(self):
86+
"""Whether finalizer is alive"""
87+
return self in self._registry
88+
89+
@property
90+
def atexit(self):
91+
"""Whether finalizer should be called at exit"""
92+
info = self._registry.get(self)
93+
return bool(info) and info.atexit
94+
95+
@atexit.setter
96+
def atexit(self, value):
97+
info = self._registry.get(self)
98+
if info:
99+
info.atexit = bool(value)
100+
101+
def __repr__(self):
102+
info = self._registry.get(self)
103+
obj = info and info.weakref()
104+
if obj is None:
105+
return "<%s object at %#x; dead>" % (type(self).__name__, id(self))
106+
else:
107+
return "<%s object at %#x; for %r at %#x>" % (
108+
type(self).__name__,
109+
id(self),
110+
type(obj).__name__,
111+
id(obj),
112+
)
113+
114+
@classmethod
115+
def _select_for_exit(cls):
116+
# Return live finalizers marked for exit, oldest first
117+
L = [(f, i) for (f, i) in cls._registry.items() if i.atexit]
118+
L.sort(key=lambda item: item[1].index)
119+
return [f for (f, i) in L]
120+
121+
@classmethod
122+
def _exitfunc(cls):
123+
# At shutdown invoke finalizers for which atexit is true.
124+
# This is called once all other non-daemonic threads have been
125+
# joined.
126+
reenable_gc = False
127+
try:
128+
if cls._registry:
129+
import gc
130+
131+
if gc.isenabled():
132+
reenable_gc = True
133+
gc.disable()
134+
pending = None
135+
while True:
136+
if pending is None or weakref_finalize._dirty:
137+
pending = cls._select_for_exit()
138+
weakref_finalize._dirty = False
139+
if not pending:
140+
break
141+
f = pending.pop()
142+
try:
143+
# gc is disabled, so (assuming no daemonic
144+
# threads) the following is the only line in
145+
# this function which might trigger creation
146+
# of a new finalizer
147+
f()
148+
except Exception:
149+
sys.excepthook(*sys.exc_info())
150+
assert f not in cls._registry
151+
finally:
152+
# prevent any more finalizers from executing during shutdown
153+
weakref_finalize._shutdown = True
154+
if reenable_gc:
155+
gc.enable()

Diff for: src/pip/_vendor/urllib3/poolmanager.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ class PoolManager(RequestMethods):
171171
def __init__(self, num_pools=10, headers=None, **connection_pool_kw):
172172
RequestMethods.__init__(self, headers)
173173
self.connection_pool_kw = connection_pool_kw
174-
self.pools = RecentlyUsedContainer(num_pools, dispose_func=lambda p: p.close())
174+
self.pools = RecentlyUsedContainer(num_pools)
175175

176176
# Locally set the pool classes and keys so other PoolManagers can
177177
# override them.

Diff for: src/pip/_vendor/vendor.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ requests==2.31.0
1111
certifi==2023.5.7
1212
chardet==5.1.0
1313
idna==3.4
14-
urllib3==1.26.15
14+
urllib3==1.26.16
1515
rich==13.4.2
1616
pygments==2.15.1
1717
typing_extensions==4.7.1

0 commit comments

Comments
 (0)