Update build-tools to ab/10084470

https://ci.android.com/builds/branches/aosp-build-tools-release/grid?head=10084470&tail=10084470

Test: treehugger
Change-Id: I8ab3e75970e3a1a5087747e978853d02a3431ed3
diff --git a/common/framework/javac_extractor.jar b/common/framework/javac_extractor.jar
index 9852442..718f020 100644
--- a/common/framework/javac_extractor.jar
+++ b/common/framework/javac_extractor.jar
Binary files differ
diff --git a/common/framework/turbine.jar b/common/framework/turbine.jar
index 21348c6..962b853 100644
--- a/common/framework/turbine.jar
+++ b/common/framework/turbine.jar
Binary files differ
diff --git a/common/py3-stdlib/LICENSE b/common/py3-stdlib/LICENSE
index 02a5145..f26bcf4 100644
--- a/common/py3-stdlib/LICENSE
+++ b/common/py3-stdlib/LICENSE
@@ -2,12 +2,12 @@
 ==========================
 
 Python was created in the early 1990s by Guido van Rossum at Stichting
-Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
+Mathematisch Centrum (CWI, see https://www.cwi.nl) in the Netherlands
 as a successor of a language called ABC.  Guido remains Python's
 principal author, although it includes many contributions from others.
 
 In 1995, Guido continued his work on Python at the Corporation for
-National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
+National Research Initiatives (CNRI, see https://www.cnri.reston.va.us)
 in Reston, Virginia where he released several versions of the
 software.
 
@@ -19,7 +19,7 @@
 created specifically to own Python-related Intellectual Property.
 Zope Corporation was a sponsoring member of the PSF.
 
-All Python releases are Open Source (see http://www.opensource.org for
+All Python releases are Open Source (see https://opensource.org for
 the Open Source Definition).  Historically, most, but not all, Python
 releases have also been GPL-compatible; the table below summarizes
 the various releases.
@@ -84,7 +84,7 @@
 distribute, and otherwise use Python alone or in any derivative version,
 provided, however, that PSF's License Agreement and PSF's notice of copyright,
 i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Python Software Foundation;
+2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Python Software Foundation;
 All Rights Reserved" are retained in Python alone or in any derivative version
 prepared by Licensee.
 
diff --git a/common/py3-stdlib/_collections_abc.py b/common/py3-stdlib/_collections_abc.py
index 40417dc..72fd633 100644
--- a/common/py3-stdlib/_collections_abc.py
+++ b/common/py3-stdlib/_collections_abc.py
@@ -441,6 +441,8 @@
     def __parameters__(self):
         params = []
         for arg in self.__args__:
+            if isinstance(arg, type) and not isinstance(arg, GenericAlias):
+                continue
             # Looks like a genericalias
             if hasattr(arg, "__parameters__") and isinstance(arg.__parameters__, tuple):
                 params.extend(arg.__parameters__)
@@ -486,6 +488,9 @@
         subst = dict(zip(self.__parameters__, item))
         new_args = []
         for arg in self.__args__:
+            if isinstance(arg, type) and not isinstance(arg, GenericAlias):
+                new_args.append(arg)
+                continue
             if _is_typevarlike(arg):
                 if _is_param_expr(arg):
                     arg = subst[arg]
diff --git a/common/py3-stdlib/argparse.py b/common/py3-stdlib/argparse.py
index 2c0dd85..736bf5a 100644
--- a/common/py3-stdlib/argparse.py
+++ b/common/py3-stdlib/argparse.py
@@ -400,10 +400,18 @@
             except ValueError:
                 continue
             else:
-                end = start + len(group._group_actions)
+                group_action_count = len(group._group_actions)
+                end = start + group_action_count
                 if actions[start:end] == group._group_actions:
+
+                    suppressed_actions_count = 0
                     for action in group._group_actions:
                         group_actions.add(action)
+                        if action.help is SUPPRESS:
+                            suppressed_actions_count += 1
+
+                    exposed_actions_count = group_action_count - suppressed_actions_count
+
                     if not group.required:
                         if start in inserts:
                             inserts[start] += ' ['
@@ -413,7 +421,7 @@
                             inserts[end] += ']'
                         else:
                             inserts[end] = ']'
-                    else:
+                    elif exposed_actions_count > 1:
                         if start in inserts:
                             inserts[start] += ' ('
                         else:
@@ -487,7 +495,6 @@
         text = _re.sub(r'(%s) ' % open, r'\1', text)
         text = _re.sub(r' (%s)' % close, r'\1', text)
         text = _re.sub(r'%s *%s' % (open, close), r'', text)
-        text = _re.sub(r'\(([^|]*)\)', r'\1', text)
         text = text.strip()
 
         # return the text
@@ -848,6 +855,7 @@
             'default',
             'type',
             'choices',
+            'required',
             'help',
             'metavar',
         ]
@@ -1961,7 +1969,11 @@
                     # arguments, try to parse more single-dash options out
                     # of the tail of the option string
                     chars = self.prefix_chars
-                    if arg_count == 0 and option_string[1] not in chars:
+                    if (
+                        arg_count == 0
+                        and option_string[1] not in chars
+                        and explicit_arg != ''
+                    ):
                         action_tuples.append((action, [], option_string))
                         char = option_string[0]
                         option_string = char + explicit_arg[0]
diff --git a/common/py3-stdlib/ast.py b/common/py3-stdlib/ast.py
index f4d2f6e..4f5f982 100644
--- a/common/py3-stdlib/ast.py
+++ b/common/py3-stdlib/ast.py
@@ -53,10 +53,12 @@
 
 def literal_eval(node_or_string):
     """
-    Safely evaluate an expression node or a string containing a Python
+    Evaluate an expression node or a string containing only a Python
     expression.  The string or node provided may only consist of the following
     Python literal structures: strings, bytes, numbers, tuples, lists, dicts,
     sets, booleans, and None.
+
+    Caution: A complex expression can overflow the C stack and cause a crash.
     """
     if isinstance(node_or_string, str):
         node_or_string = parse(node_or_string.lstrip(" \t"), mode='eval')
@@ -234,6 +236,12 @@
     location in a file.
     """
     for child in walk(node):
+        # TypeIgnore is a special case where lineno is not an attribute
+        # but rather a field of the node itself.
+        if isinstance(child, TypeIgnore):
+            child.lineno = getattr(child, 'lineno', 0) + n
+            continue
+
         if 'lineno' in child._attributes:
             child.lineno = getattr(child, 'lineno', 0) + n
         if (
@@ -849,7 +857,7 @@
 
     def visit_ImportFrom(self, node):
         self.fill("from ")
-        self.write("." * node.level)
+        self.write("." * (node.level or 0))
         if node.module:
             self.write(node.module)
         self.write(" import ")
diff --git a/common/py3-stdlib/asynchat.py b/common/py3-stdlib/asynchat.py
index de26ffa..e081e67 100644
--- a/common/py3-stdlib/asynchat.py
+++ b/common/py3-stdlib/asynchat.py
@@ -50,7 +50,7 @@
 
 from warnings import warn
 warn(
-    'The asynchat module is deprecated. '
+    'The asynchat module is deprecated and will be removed in Python 3.12. '
     'The recommended replacement is asyncio',
     DeprecationWarning,
     stacklevel=2)
diff --git a/common/py3-stdlib/asyncio/base_events.py b/common/py3-stdlib/asyncio/base_events.py
index 952da11..0890e9e 100644
--- a/common/py3-stdlib/asyncio/base_events.py
+++ b/common/py3-stdlib/asyncio/base_events.py
@@ -573,9 +573,11 @@
     def _do_shutdown(self, future):
         try:
             self._default_executor.shutdown(wait=True)
-            self.call_soon_threadsafe(future.set_result, None)
+            if not self.is_closed():
+                self.call_soon_threadsafe(future.set_result, None)
         except Exception as ex:
-            self.call_soon_threadsafe(future.set_exception, ex)
+            if not self.is_closed():
+                self.call_soon_threadsafe(future.set_exception, ex)
 
     def _check_running(self):
         if self.is_running():
@@ -589,12 +591,13 @@
         self._check_closed()
         self._check_running()
         self._set_coroutine_origin_tracking(self._debug)
-        self._thread_id = threading.get_ident()
 
         old_agen_hooks = sys.get_asyncgen_hooks()
-        sys.set_asyncgen_hooks(firstiter=self._asyncgen_firstiter_hook,
-                               finalizer=self._asyncgen_finalizer_hook)
         try:
+            self._thread_id = threading.get_ident()
+            sys.set_asyncgen_hooks(firstiter=self._asyncgen_firstiter_hook,
+                                   finalizer=self._asyncgen_finalizer_hook)
+
             events._set_running_loop(self)
             while True:
                 self._run_once()
@@ -884,7 +887,7 @@
         # non-mmap files even if sendfile is supported by OS
         raise exceptions.SendfileNotAvailableError(
             f"syscall sendfile is not available for socket {sock!r} "
-            "and file {file!r} combination")
+            f"and file {file!r} combination")
 
     async def _sock_sendfile_fallback(self, sock, file, offset, count):
         if offset:
@@ -943,7 +946,10 @@
             sock = socket.socket(family=family, type=type_, proto=proto)
             sock.setblocking(False)
             if local_addr_infos is not None:
-                for _, _, _, _, laddr in local_addr_infos:
+                for lfamily, _, _, _, laddr in local_addr_infos:
+                    # skip local addresses of different family
+                    if lfamily != family:
+                        continue
                     try:
                         sock.bind(laddr)
                         break
@@ -956,7 +962,10 @@
                         exc = OSError(exc.errno, msg)
                         my_exceptions.append(exc)
                 else:  # all bind attempts failed
-                    raise my_exceptions.pop()
+                    if my_exceptions:
+                        raise my_exceptions.pop()
+                    else:
+                        raise OSError(f"no matching local address with {family=} found")
             await self.sock_connect(sock, address)
             return sock
         except OSError as exc:
@@ -968,6 +977,8 @@
             if sock is not None:
                 sock.close()
             raise
+        finally:
+            exceptions = my_exceptions = None
 
     async def create_connection(
             self, protocol_factory, host=None, port=None,
@@ -1060,17 +1071,20 @@
 
             if sock is None:
                 exceptions = [exc for sub in exceptions for exc in sub]
-                if len(exceptions) == 1:
-                    raise exceptions[0]
-                else:
-                    # If they all have the same str(), raise one.
-                    model = str(exceptions[0])
-                    if all(str(exc) == model for exc in exceptions):
+                try:
+                    if len(exceptions) == 1:
                         raise exceptions[0]
-                    # Raise a combined exception so the user can see all
-                    # the various error messages.
-                    raise OSError('Multiple exceptions: {}'.format(
-                        ', '.join(str(exc) for exc in exceptions)))
+                    else:
+                        # If they all have the same str(), raise one.
+                        model = str(exceptions[0])
+                        if all(str(exc) == model for exc in exceptions):
+                            raise exceptions[0]
+                        # Raise a combined exception so the user can see all
+                        # the various error messages.
+                        raise OSError('Multiple exceptions: {}'.format(
+                            ', '.join(str(exc) for exc in exceptions)))
+                finally:
+                    exceptions = None
 
         else:
             if sock is None:
@@ -1801,12 +1815,9 @@
                                  exc_info=True)
 
     def _add_callback(self, handle):
-        """Add a Handle to _scheduled (TimerHandle) or _ready."""
-        assert isinstance(handle, events.Handle), 'A Handle is required here'
-        if handle._cancelled:
-            return
-        assert not isinstance(handle, events.TimerHandle)
-        self._ready.append(handle)
+        """Add a Handle to _ready."""
+        if not handle._cancelled:
+            self._ready.append(handle)
 
     def _add_callback_signalsafe(self, handle):
         """Like _add_callback() but called from a signal handler."""
@@ -1859,6 +1870,8 @@
 
         event_list = self._selector.select(timeout)
         self._process_events(event_list)
+        # Needed to break cycles when an exception occurs.
+        event_list = None
 
         # Handle 'later' callbacks that are ready.
         end_time = self.time() + self._clock_resolution
diff --git a/common/py3-stdlib/asyncio/events.py b/common/py3-stdlib/asyncio/events.py
index 5ab1acc..e088230 100644
--- a/common/py3-stdlib/asyncio/events.py
+++ b/common/py3-stdlib/asyncio/events.py
@@ -763,12 +763,13 @@
 
 
 def _get_event_loop(stacklevel=3):
+    # This internal method is going away in Python 3.12, left here only for
+    # backwards compatibility with 3.10.0 - 3.10.8 and 3.11.0.
+    # Similarly, this method's C equivalent in _asyncio is going away as well.
+    # See GH-99949 for more details.
     current_loop = _get_running_loop()
     if current_loop is not None:
         return current_loop
-    import warnings
-    warnings.warn('There is no current event loop',
-                  DeprecationWarning, stacklevel=stacklevel)
     return get_event_loop_policy().get_event_loop()
 
 
diff --git a/common/py3-stdlib/asyncio/futures.py b/common/py3-stdlib/asyncio/futures.py
index 8e8cd87..5d00ab4 100644
--- a/common/py3-stdlib/asyncio/futures.py
+++ b/common/py3-stdlib/asyncio/futures.py
@@ -198,7 +198,7 @@
             raise exceptions.InvalidStateError('Result is not ready.')
         self.__log_traceback = False
         if self._exception is not None:
-            raise self._exception
+            raise self._exception.with_traceback(self._exception_tb)
         return self._result
 
     def exception(self):
@@ -274,6 +274,7 @@
             raise TypeError("StopIteration interacts badly with generators "
                             "and cannot be raised into a Future")
         self._exception = exception
+        self._exception_tb = exception.__traceback__
         self._state = _FINISHED
         self.__schedule_callbacks()
         self.__log_traceback = True
@@ -395,6 +396,8 @@
         if dest_loop is None or dest_loop is source_loop:
             _set_state(destination, source)
         else:
+            if dest_loop.is_closed():
+                return
             dest_loop.call_soon_threadsafe(_set_state, destination, source)
 
     destination.add_done_callback(_call_check_cancel)
diff --git a/common/py3-stdlib/asyncio/locks.py b/common/py3-stdlib/asyncio/locks.py
index 4fef64e..e192159 100644
--- a/common/py3-stdlib/asyncio/locks.py
+++ b/common/py3-stdlib/asyncio/locks.py
@@ -6,6 +6,7 @@
 
 from . import exceptions
 from . import mixins
+from . import tasks
 
 
 class _ContextManagerMixin:
@@ -348,8 +349,8 @@
         super().__init__(loop=loop)
         if value < 0:
             raise ValueError("Semaphore initial value must be >= 0")
+        self._waiters = None
         self._value = value
-        self._waiters = collections.deque()
 
     def __repr__(self):
         res = super().__repr__()
@@ -358,16 +359,10 @@
             extra = f'{extra}, waiters:{len(self._waiters)}'
         return f'<{res[1:-1]} [{extra}]>'
 
-    def _wake_up_next(self):
-        while self._waiters:
-            waiter = self._waiters.popleft()
-            if not waiter.done():
-                waiter.set_result(None)
-                return
-
     def locked(self):
-        """Returns True if semaphore can not be acquired immediately."""
-        return self._value == 0
+        """Returns True if semaphore cannot be acquired immediately."""
+        return self._value == 0 or (
+            any(not w.cancelled() for w in (self._waiters or ())))
 
     async def acquire(self):
         """Acquire a semaphore.
@@ -378,28 +373,53 @@
         called release() to make it larger than 0, and then return
         True.
         """
-        while self._value <= 0:
-            fut = self._get_loop().create_future()
-            self._waiters.append(fut)
+        if not self.locked():
+            self._value -= 1
+            return True
+
+        if self._waiters is None:
+            self._waiters = collections.deque()
+        fut = self._get_loop().create_future()
+        self._waiters.append(fut)
+
+        # Finally block should be called before the CancelledError
+        # handling as we don't want CancelledError to call
+        # _wake_up_first() and attempt to wake up itself.
+        try:
             try:
                 await fut
-            except:
-                # See the similar code in Queue.get.
-                fut.cancel()
-                if self._value > 0 and not fut.cancelled():
-                    self._wake_up_next()
-                raise
-        self._value -= 1
+            finally:
+                self._waiters.remove(fut)
+        except exceptions.CancelledError:
+            if not fut.cancelled():
+                self._value += 1
+                self._wake_up_next()
+            raise
+
+        if self._value > 0:
+            self._wake_up_next()
         return True
 
     def release(self):
         """Release a semaphore, incrementing the internal counter by one.
+
         When it was zero on entry and another coroutine is waiting for it to
         become larger than zero again, wake up that coroutine.
         """
         self._value += 1
         self._wake_up_next()
 
+    def _wake_up_next(self):
+        """Wake up the first waiter that isn't done."""
+        if not self._waiters:
+            return
+
+        for fut in self._waiters:
+            if not fut.done():
+                self._value -= 1
+                fut.set_result(True)
+                return
+
 
 class BoundedSemaphore(Semaphore):
     """A bounded semaphore implementation.
diff --git a/common/py3-stdlib/asyncio/proactor_events.py b/common/py3-stdlib/asyncio/proactor_events.py
index 411685b..0916d9e 100644
--- a/common/py3-stdlib/asyncio/proactor_events.py
+++ b/common/py3-stdlib/asyncio/proactor_events.py
@@ -60,6 +60,7 @@
         self._pending_write = 0
         self._conn_lost = 0
         self._closing = False  # Set when close() called.
+        self._called_connection_lost = False
         self._eof_written = False
         if self._server is not None:
             self._server._attach()
@@ -113,7 +114,7 @@
     def __del__(self, _warn=warnings.warn):
         if self._sock is not None:
             _warn(f"unclosed transport {self!r}", ResourceWarning, source=self)
-            self.close()
+            self._sock.close()
 
     def _fatal_error(self, exc, message='Fatal error on pipe transport'):
         try:
@@ -136,7 +137,7 @@
                 self._empty_waiter.set_result(None)
             else:
                 self._empty_waiter.set_exception(exc)
-        if self._closing:
+        if self._closing and self._called_connection_lost:
             return
         self._closing = True
         self._conn_lost += 1
@@ -151,6 +152,8 @@
         self._loop.call_soon(self._call_connection_lost, exc)
 
     def _call_connection_lost(self, exc):
+        if self._called_connection_lost:
+            return
         try:
             self._protocol.connection_lost(exc)
         finally:
@@ -166,6 +169,7 @@
             if server is not None:
                 server._detach()
                 self._server = None
+            self._called_connection_lost = True
 
     def get_write_buffer_size(self):
         size = self._pending_write
diff --git a/common/py3-stdlib/asyncio/selector_events.py b/common/py3-stdlib/asyncio/selector_events.py
index 71080b8..8282f28 100644
--- a/common/py3-stdlib/asyncio/selector_events.py
+++ b/common/py3-stdlib/asyncio/selector_events.py
@@ -487,7 +487,8 @@
         if self._debug and sock.gettimeout() != 0:
             raise ValueError("the socket must be non-blocking")
 
-        if not hasattr(socket, 'AF_UNIX') or sock.family != socket.AF_UNIX:
+        if sock.family == socket.AF_INET or (
+                base_events._HAS_IPv6 and sock.family == socket.AF_INET6):
             resolved = await self._ensure_resolved(
                 address, family=sock.family, type=sock.type, proto=sock.proto,
                 loop=self,
@@ -496,7 +497,11 @@
 
         fut = self.create_future()
         self._sock_connect(fut, sock, address)
-        return await fut
+        try:
+            return await fut
+        finally:
+            # Needed to break cycles when an exception occurs.
+            fut = None
 
     def _sock_connect(self, fut, sock, address):
         fd = sock.fileno()
@@ -518,6 +523,8 @@
             fut.set_exception(exc)
         else:
             fut.set_result(None)
+        finally:
+            fut = None
 
     def _sock_write_done(self, fd, fut, handle=None):
         if handle is None or not handle.cancelled():
@@ -541,6 +548,8 @@
             fut.set_exception(exc)
         else:
             fut.set_result(None)
+        finally:
+            fut = None
 
     async def sock_accept(self, sock):
         """Accept a connection.
diff --git a/common/py3-stdlib/asyncio/streams.py b/common/py3-stdlib/asyncio/streams.py
index 080d8a6..37fa7dc 100644
--- a/common/py3-stdlib/asyncio/streams.py
+++ b/common/py3-stdlib/asyncio/streams.py
@@ -2,6 +2,7 @@
     'StreamReader', 'StreamWriter', 'StreamReaderProtocol',
     'open_connection', 'start_server')
 
+import collections
 import socket
 import sys
 import warnings
@@ -129,7 +130,7 @@
         else:
             self._loop = loop
         self._paused = False
-        self._drain_waiter = None
+        self._drain_waiters = collections.deque()
         self._connection_lost = False
 
     def pause_writing(self):
@@ -144,38 +145,34 @@
         if self._loop.get_debug():
             logger.debug("%r resumes writing", self)
 
-        waiter = self._drain_waiter
-        if waiter is not None:
-            self._drain_waiter = None
+        for waiter in self._drain_waiters:
             if not waiter.done():
                 waiter.set_result(None)
 
     def connection_lost(self, exc):
         self._connection_lost = True
-        # Wake up the writer if currently paused.
+        # Wake up the writer(s) if currently paused.
         if not self._paused:
             return
-        waiter = self._drain_waiter
-        if waiter is None:
-            return
-        self._drain_waiter = None
-        if waiter.done():
-            return
-        if exc is None:
-            waiter.set_result(None)
-        else:
-            waiter.set_exception(exc)
+
+        for waiter in self._drain_waiters:
+            if not waiter.done():
+                if exc is None:
+                    waiter.set_result(None)
+                else:
+                    waiter.set_exception(exc)
 
     async def _drain_helper(self):
         if self._connection_lost:
             raise ConnectionResetError('Connection lost')
         if not self._paused:
             return
-        waiter = self._drain_waiter
-        assert waiter is None or waiter.cancelled()
         waiter = self._loop.create_future()
-        self._drain_waiter = waiter
-        await waiter
+        self._drain_waiters.append(waiter)
+        try:
+            await waiter
+        finally:
+            self._drain_waiters.remove(waiter)
 
     def _get_close_waiter(self, stream):
         raise NotImplementedError
@@ -206,6 +203,7 @@
             self._strong_reader = stream_reader
         self._reject_connection = False
         self._stream_writer = None
+        self._task = None
         self._transport = None
         self._client_connected_cb = client_connected_cb
         self._over_ssl = False
@@ -241,7 +239,7 @@
             res = self._client_connected_cb(reader,
                                             self._stream_writer)
             if coroutines.iscoroutine(res):
-                self._loop.create_task(res)
+                self._task = self._loop.create_task(res)
             self._strong_reader = None
 
     def connection_lost(self, exc):
@@ -259,6 +257,7 @@
         super().connection_lost(exc)
         self._stream_reader_wr = None
         self._stream_writer = None
+        self._task = None
         self._transport = None
 
     def data_received(self, data):
@@ -628,16 +627,17 @@
     async def read(self, n=-1):
         """Read up to `n` bytes from the stream.
 
-        If n is not provided, or set to -1, read until EOF and return all read
-        bytes. If the EOF was received and the internal buffer is empty, return
-        an empty bytes object.
+        If `n` is not provided or set to -1,
+        read until EOF, then return all read bytes.
+        If EOF was received and the internal buffer is empty,
+        return an empty bytes object.
 
-        If n is zero, return empty bytes object immediately.
+        If `n` is 0, return an empty bytes object immediately.
 
-        If n is positive, this function try to read `n` bytes, and may return
-        less or equal bytes than requested, but at least one byte. If EOF was
-        received before any byte is read, this function returns empty byte
-        object.
+        If `n` is positive, return at most `n` available bytes
+        as soon as at least 1 byte is available in the internal buffer.
+        If EOF is received before any byte is read, return an empty
+        bytes object.
 
         Returned value is not limited with limit, configured at stream
         creation.
diff --git a/common/py3-stdlib/asyncio/tasks.py b/common/py3-stdlib/asyncio/tasks.py
index c4bedb5..f391586 100644
--- a/common/py3-stdlib/asyncio/tasks.py
+++ b/common/py3-stdlib/asyncio/tasks.py
@@ -809,7 +809,8 @@
 
     The statement
 
-        res = await shield(something())
+        task = asyncio.create_task(something())
+        res = await shield(task)
 
     is exactly equivalent to the statement
 
@@ -825,10 +826,16 @@
     If you want to completely ignore cancellation (not recommended)
     you can combine shield() with a try/except clause, as follows:
 
+        task = asyncio.create_task(something())
         try:
-            res = await shield(something())
+            res = await shield(task)
         except CancelledError:
             res = None
+
+    Save a reference to tasks passed to this function, to avoid
+    a task disappearing mid-execution. The event loop only keeps
+    weak references to tasks. A task that isn't referenced elsewhere
+    may get garbage collected at any time, even before it's done.
     """
     inner = _ensure_future(arg)
     if inner.done():
diff --git a/common/py3-stdlib/asyncio/unix_events.py b/common/py3-stdlib/asyncio/unix_events.py
index c88b818..faaca30 100644
--- a/common/py3-stdlib/asyncio/unix_events.py
+++ b/common/py3-stdlib/asyncio/unix_events.py
@@ -223,7 +223,8 @@
         return transp
 
     def _child_watcher_callback(self, pid, returncode, transp):
-        self.call_soon_threadsafe(transp._process_exited, returncode)
+        # Skip one iteration for callbacks to be executed
+        self.call_soon_threadsafe(self.call_soon, transp._process_exited, returncode)
 
     async def create_unix_connection(
             self, protocol_factory, path=None, *,
@@ -788,12 +789,11 @@
 
     def _start(self, args, shell, stdin, stdout, stderr, bufsize, **kwargs):
         stdin_w = None
-        if stdin == subprocess.PIPE:
-            # Use a socket pair for stdin, since not all platforms
+        if stdin == subprocess.PIPE and sys.platform.startswith('aix'):
+            # Use a socket pair for stdin on AIX, since it does not
             # support selecting read events on the write end of a
             # socket (which we use in order to detect closing of the
-            # other end).  Notably this is needed on AIX, and works
-            # just fine on other platforms.
+            # other end).
             stdin, stdin_w = socket.socketpair()
         try:
             self._proc = subprocess.Popen(
diff --git a/common/py3-stdlib/asyncio/windows_events.py b/common/py3-stdlib/asyncio/windows_events.py
index da81ab4..3204c7c 100644
--- a/common/py3-stdlib/asyncio/windows_events.py
+++ b/common/py3-stdlib/asyncio/windows_events.py
@@ -366,6 +366,10 @@
                     return
 
                 f = self._proactor.accept_pipe(pipe)
+            except BrokenPipeError:
+                if pipe and pipe.fileno() != -1:
+                    pipe.close()
+                self.call_soon(loop_accept_pipe)
             except OSError as exc:
                 if pipe and pipe.fileno() != -1:
                     self.call_exception_handler({
@@ -377,6 +381,7 @@
                 elif self._debug:
                     logger.warning("Accept pipe failed on pipe %r",
                                    pipe, exc_info=True)
+                self.call_soon(loop_accept_pipe)
             except exceptions.CancelledError:
                 if pipe:
                     pipe.close()
@@ -439,7 +444,11 @@
             self._poll(timeout)
         tmp = self._results
         self._results = []
-        return tmp
+        try:
+            return tmp
+        finally:
+            # Needed to break cycles when an exception occurs.
+            tmp = None
 
     def _result(self, value):
         fut = self._loop.create_future()
@@ -821,6 +830,8 @@
                 else:
                     f.set_result(value)
                     self._results.append(f)
+                finally:
+                    f = None
 
         # Remove unregistered futures
         for ov in self._unregistered:
diff --git a/common/py3-stdlib/asyncore.py b/common/py3-stdlib/asyncore.py
index b1eea4b..a360d40 100644
--- a/common/py3-stdlib/asyncore.py
+++ b/common/py3-stdlib/asyncore.py
@@ -58,7 +58,7 @@
      errorcode
 
 warnings.warn(
-    'The asyncore module is deprecated. '
+    'The asyncore module is deprecated and will be removed in Python 3.12. '
     'The recommended replacement is asyncio',
     DeprecationWarning,
     stacklevel=2)
diff --git a/common/py3-stdlib/bdb.py b/common/py3-stdlib/bdb.py
index 75d6113..7f9b095 100644
--- a/common/py3-stdlib/bdb.py
+++ b/common/py3-stdlib/bdb.py
@@ -570,9 +570,10 @@
             rv = frame.f_locals['__return__']
             s += '->'
             s += reprlib.repr(rv)
-        line = linecache.getline(filename, lineno, frame.f_globals)
-        if line:
-            s += lprefix + line.strip()
+        if lineno is not None:
+            line = linecache.getline(filename, lineno, frame.f_globals)
+            if line:
+                s += lprefix + line.strip()
         return s
 
     # The following methods can be called by clients to use
@@ -805,15 +806,18 @@
     return True
 
 
-# Determines if there is an effective (active) breakpoint at this
-# line of code.  Returns breakpoint number or 0 if none
 def effective(file, line, frame):
-    """Determine which breakpoint for this file:line is to be acted upon.
+    """Return (active breakpoint, delete temporary flag) or (None, None) as
+       breakpoint to act upon.
 
-    Called only if we know there is a breakpoint at this location.  Return
-    the breakpoint that was triggered and a boolean that indicates if it is
-    ok to delete a temporary breakpoint.  Return (None, None) if there is no
-    matching breakpoint.
+       The "active breakpoint" is the first entry in bplist[line, file] (which
+       must exist) that is enabled, for which checkfuncname is True, and that
+       has neither a False condition nor a positive ignore count.  The flag,
+       meaning that a temporary breakpoint should be deleted, is False only
+       when the condiion cannot be evaluated (in which case, ignore count is
+       ignored).
+
+       If no such entry exists, then (None, None) is returned.
     """
     possibles = Breakpoint.bplist[file, line]
     for b in possibles:
diff --git a/common/py3-stdlib/codecs.py b/common/py3-stdlib/codecs.py
index e6ad6e3..3b173b6 100644
--- a/common/py3-stdlib/codecs.py
+++ b/common/py3-stdlib/codecs.py
@@ -878,7 +878,8 @@
         codecs. Output is also codec dependent and will usually be
         Unicode as well.
 
-        Underlying encoded files are always opened in binary mode.
+        If encoding is not None, then the
+        underlying encoded files are always opened in binary mode.
         The default file mode is 'r', meaning to open the file in read mode.
 
         encoding specifies the encoding which is to be used for the
diff --git a/common/py3-stdlib/codeop.py b/common/py3-stdlib/codeop.py
index 568e9bb..fe8713e 100644
--- a/common/py3-stdlib/codeop.py
+++ b/common/py3-stdlib/codeop.py
@@ -56,22 +56,22 @@
         if symbol != "eval":
             source = "pass"     # Replace it with a 'pass' statement
 
-    try:
-        return compiler(source, filename, symbol)
-    except SyntaxError:  # Let other compile() errors propagate.
-        pass
-
-    # Catch syntax warnings after the first compile
-    # to emit warnings (SyntaxWarning, DeprecationWarning) at most once.
+    # Disable compiler warnings when checking for incomplete input.
     with warnings.catch_warnings():
-        warnings.simplefilter("error")
-
+        warnings.simplefilter("ignore", (SyntaxWarning, DeprecationWarning))
         try:
-            compiler(source + "\n", filename, symbol)
-        except SyntaxError as e:
-            if "incomplete input" in str(e):
+            compiler(source, filename, symbol)
+        except SyntaxError:  # Let other compile() errors propagate.
+            try:
+                compiler(source + "\n", filename, symbol)
                 return None
-            raise
+            except SyntaxError as e:
+                if "incomplete input" in str(e):
+                    return None
+                # fallthrough
+
+    return compiler(source, filename, symbol)
+
 
 def _is_syntax_error(err1, err2):
     rep1 = repr(err1)
diff --git a/common/py3-stdlib/compileall.py b/common/py3-stdlib/compileall.py
index 3755e76..50183ea 100644
--- a/common/py3-stdlib/compileall.py
+++ b/common/py3-stdlib/compileall.py
@@ -154,8 +154,8 @@
                           "in combination with stripdir or prependdir"))
 
     success = True
-    if quiet < 2 and isinstance(fullname, os.PathLike):
-        fullname = os.fspath(fullname)
+    fullname = os.fspath(fullname)
+    stripdir = os.fspath(stripdir) if stripdir is not None else None
     name = os.path.basename(fullname)
 
     dfile = None
diff --git a/common/py3-stdlib/concurrent/futures/_base.py b/common/py3-stdlib/concurrent/futures/_base.py
index 5c00f2e..a329e74 100644
--- a/common/py3-stdlib/concurrent/futures/_base.py
+++ b/common/py3-stdlib/concurrent/futures/_base.py
@@ -312,6 +312,18 @@
     done.update(waiter.finished_futures)
     return DoneAndNotDoneFutures(done, fs - done)
 
+
+def _result_or_cancel(fut, timeout=None):
+    try:
+        try:
+            return fut.result(timeout)
+        finally:
+            fut.cancel()
+    finally:
+        # Break a reference cycle with the exception in self._exception
+        del fut
+
+
 class Future(object):
     """Represents the result of an asynchronous computation."""
 
@@ -381,7 +393,7 @@
             return self._state == RUNNING
 
     def done(self):
-        """Return True of the future was cancelled or finished executing."""
+        """Return True if the future was cancelled or finished executing."""
         with self._condition:
             return self._state in [CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED]
 
@@ -606,9 +618,9 @@
                 while fs:
                     # Careful not to keep a reference to the popped future
                     if timeout is None:
-                        yield fs.pop().result()
+                        yield _result_or_cancel(fs.pop())
                     else:
-                        yield fs.pop().result(end_time - time.monotonic())
+                        yield _result_or_cancel(fs.pop(), end_time - time.monotonic())
             finally:
                 for future in fs:
                     future.cancel()
diff --git a/common/py3-stdlib/concurrent/futures/process.py b/common/py3-stdlib/concurrent/futures/process.py
index 6ee2ce6..81cc1fb 100644
--- a/common/py3-stdlib/concurrent/futures/process.py
+++ b/common/py3-stdlib/concurrent/futures/process.py
@@ -126,6 +126,9 @@
         tb = traceback.format_exception(type(exc), exc, tb)
         tb = ''.join(tb)
         self.exc = exc
+        # Traceback object needs to be garbage-collected as its frames
+        # contain references to all the objects in the exception scope
+        self.exc.__traceback__ = None
         self.tb = '\n"""\n%s"""' % tb
     def __reduce__(self):
         return _rebuild_exc, (self.exc, self.tb)
@@ -334,6 +337,11 @@
             if self.is_shutting_down():
                 self.flag_executor_shutting_down()
 
+                # When only canceled futures remain in pending_work_items, our
+                # next call to wait_result_broken_or_wakeup would hang forever.
+                # This makes sure we have some running futures or none at all.
+                self.add_call_item_to_queue()
+
                 # Since no new work items can be added, it is safe to shutdown
                 # this thread if there are no pending work items.
                 if not self.pending_work_items:
@@ -612,6 +620,10 @@
             mp_context = mp.get_context()
         self._mp_context = mp_context
 
+        # https://github.com/python/cpython/issues/90622
+        self._safe_to_dynamically_spawn_children = (
+                self._mp_context.get_start_method(allow_none=False) != "fork")
+
         if initializer is not None and not callable(initializer):
             raise TypeError("initializer must be a callable")
         self._initializer = initializer
@@ -662,6 +674,8 @@
     def _start_executor_manager_thread(self):
         if self._executor_manager_thread is None:
             # Start the processes so that their sentinels are known.
+            if not self._safe_to_dynamically_spawn_children:  # ie, using fork.
+                self._launch_processes()
             self._executor_manager_thread = _ExecutorManagerThread(self)
             self._executor_manager_thread.start()
             _threads_wakeups[self._executor_manager_thread] = \
@@ -674,14 +688,31 @@
 
         process_count = len(self._processes)
         if process_count < self._max_workers:
-            p = self._mp_context.Process(
-                target=_process_worker,
-                args=(self._call_queue,
-                      self._result_queue,
-                      self._initializer,
-                      self._initargs))
-            p.start()
-            self._processes[p.pid] = p
+            # Assertion disabled as this codepath is also used to replace a
+            # worker that unexpectedly dies, even when using the 'fork' start
+            # method. That means there is still a potential deadlock bug. If a
+            # 'fork' mp_context worker dies, we'll be forking a new one when
+            # we know a thread is running (self._executor_manager_thread).
+            #assert self._safe_to_dynamically_spawn_children or not self._executor_manager_thread, 'https://github.com/python/cpython/issues/90622'
+            self._spawn_process()
+
+    def _launch_processes(self):
+        # https://github.com/python/cpython/issues/90622
+        assert not self._executor_manager_thread, (
+                'Processes cannot be fork()ed after the thread has started, '
+                'deadlock in the child processes could result.')
+        for _ in range(len(self._processes), self._max_workers):
+            self._spawn_process()
+
+    def _spawn_process(self):
+        p = self._mp_context.Process(
+            target=_process_worker,
+            args=(self._call_queue,
+                  self._result_queue,
+                  self._initializer,
+                  self._initargs))
+        p.start()
+        self._processes[p.pid] = p
 
     def submit(self, fn, /, *args, **kwargs):
         with self._shutdown_lock:
@@ -702,7 +733,8 @@
             # Wake up queue management thread
             self._executor_manager_thread_wakeup.wakeup()
 
-            self._adjust_process_count()
+            if self._safe_to_dynamically_spawn_children:
+                self._adjust_process_count()
             self._start_executor_manager_thread()
             return f
     submit.__doc__ = _base.Executor.submit.__doc__
diff --git a/common/py3-stdlib/configparser.py b/common/py3-stdlib/configparser.py
index 3470624..7855270 100644
--- a/common/py3-stdlib/configparser.py
+++ b/common/py3-stdlib/configparser.py
@@ -19,36 +19,37 @@
              inline_comment_prefixes=None, strict=True,
              empty_lines_in_values=True, default_section='DEFAULT',
              interpolation=<unset>, converters=<unset>):
-        Create the parser. When `defaults' is given, it is initialized into the
+
+        Create the parser. When `defaults` is given, it is initialized into the
         dictionary or intrinsic defaults. The keys must be strings, the values
         must be appropriate for %()s string interpolation.
 
-        When `dict_type' is given, it will be used to create the dictionary
+        When `dict_type` is given, it will be used to create the dictionary
         objects for the list of sections, for the options within a section, and
         for the default values.
 
-        When `delimiters' is given, it will be used as the set of substrings
+        When `delimiters` is given, it will be used as the set of substrings
         that divide keys from values.
 
-        When `comment_prefixes' is given, it will be used as the set of
+        When `comment_prefixes` is given, it will be used as the set of
         substrings that prefix comments in empty lines. Comments can be
         indented.
 
-        When `inline_comment_prefixes' is given, it will be used as the set of
+        When `inline_comment_prefixes` is given, it will be used as the set of
         substrings that prefix comments in non-empty lines.
 
         When `strict` is True, the parser won't allow for any section or option
         duplicates while reading from a single source (file, string or
         dictionary). Default is True.
 
-        When `empty_lines_in_values' is False (default: True), each empty line
+        When `empty_lines_in_values` is False (default: True), each empty line
         marks the end of an option. Otherwise, internal empty lines of
         a multiline option are kept as part of the value.
 
-        When `allow_no_value' is True (default: False), options without
+        When `allow_no_value` is True (default: False), options without
         values are accepted; the value presented for these is None.
 
-        When `default_section' is given, the name of the special section is
+        When `default_section` is given, the name of the special section is
         named accordingly. By default it is called ``"DEFAULT"`` but this can
         be customized to point to any other valid section name. Its current
         value can be retrieved using the ``parser_instance.default_section``
@@ -87,7 +88,7 @@
     read_file(f, filename=None)
         Read and parse one configuration file, given as a file object.
         The filename defaults to f.name; it is only used in error
-        messages (if f has no `name' attribute, the string `<???>' is used).
+        messages (if f has no `name` attribute, the string `<???>` is used).
 
     read_string(string)
         Read configuration from a given string.
@@ -103,9 +104,9 @@
         Return a string value for the named option.  All % interpolations are
         expanded in the return values, based on the defaults passed into the
         constructor and the DEFAULT section.  Additional substitutions may be
-        provided using the `vars' argument, which must be a dictionary whose
-        contents override any pre-existing defaults. If `option' is a key in
-        `vars', the value from `vars' is used.
+        provided using the `vars` argument, which must be a dictionary whose
+        contents override any pre-existing defaults. If `option` is a key in
+        `vars`, the value from `vars` is used.
 
     getint(section, options, raw=False, vars=None, fallback=_UNSET)
         Like get(), but convert value to an integer.
@@ -134,7 +135,7 @@
 
     write(fp, space_around_delimiters=True)
         Write the configuration state in .ini format. If
-        `space_around_delimiters' is True (the default), delimiters
+        `space_around_delimiters` is True (the default), delimiters
         between keys and values are surrounded by spaces.
 """
 
@@ -352,7 +353,7 @@
 
 
 # Used in parser getters to indicate the default behaviour when a specific
-# option is not found it to raise an exception. Created to enable `None' as
+# option is not found it to raise an exception. Created to enable `None` as
 # a valid fallback value.
 _UNSET = object()
 
@@ -386,7 +387,7 @@
     would resolve the "%(dir)s" to the value of dir.  All reference
     expansions are done late, on demand. If a user needs to use a bare % in
     a configuration file, she can escape it by writing %%. Other % usage
-    is considered a user error and raises `InterpolationSyntaxError'."""
+    is considered a user error and raises `InterpolationSyntaxError`."""
 
     _KEYCRE = re.compile(r"%\(([^)]+)\)s")
 
@@ -447,7 +448,7 @@
 
 class ExtendedInterpolation(Interpolation):
     """Advanced variant of interpolation, supports the syntax used by
-    `zc.buildout'. Enables interpolation between sections."""
+    `zc.buildout`. Enables interpolation between sections."""
 
     _KEYCRE = re.compile(r"\$\{([^}]+)\}")
 
@@ -706,10 +707,10 @@
     def read_file(self, f, source=None):
         """Like read() but the argument must be a file-like object.
 
-        The `f' argument must be iterable, returning one line at a time.
-        Optional second argument is the `source' specifying the name of the
-        file being read. If not given, it is taken from f.name. If `f' has no
-        `name' attribute, `<???>' is used.
+        The `f` argument must be iterable, returning one line at a time.
+        Optional second argument is the `source` specifying the name of the
+        file being read. If not given, it is taken from f.name. If `f` has no
+        `name` attribute, `<???>` is used.
         """
         if source is None:
             try:
@@ -733,7 +734,7 @@
         All types held in the dictionary are converted to strings during
         reading, including section names, option names and keys.
 
-        Optional second argument is the `source' specifying the name of the
+        Optional second argument is the `source` specifying the name of the
         dictionary being read.
         """
         elements_added = set()
@@ -766,15 +767,15 @@
     def get(self, section, option, *, raw=False, vars=None, fallback=_UNSET):
         """Get an option value for a given section.
 
-        If `vars' is provided, it must be a dictionary. The option is looked up
-        in `vars' (if provided), `section', and in `DEFAULTSECT' in that order.
-        If the key is not found and `fallback' is provided, it is used as
-        a fallback value. `None' can be provided as a `fallback' value.
+        If `vars` is provided, it must be a dictionary. The option is looked up
+        in `vars` (if provided), `section`, and in `DEFAULTSECT` in that order.
+        If the key is not found and `fallback` is provided, it is used as
+        a fallback value. `None` can be provided as a `fallback` value.
 
-        If interpolation is enabled and the optional argument `raw' is False,
+        If interpolation is enabled and the optional argument `raw` is False,
         all interpolations are expanded in the return values.
 
-        Arguments `raw', `vars', and `fallback' are keyword only.
+        Arguments `raw`, `vars`, and `fallback` are keyword only.
 
         The section DEFAULT is special.
         """
@@ -834,8 +835,8 @@
 
         All % interpolations are expanded in the return values, based on the
         defaults passed into the constructor, unless the optional argument
-        `raw' is true.  Additional substitutions may be provided using the
-        `vars' argument, which must be a dictionary whose contents overrides
+        `raw` is true.  Additional substitutions may be provided using the
+        `vars` argument, which must be a dictionary whose contents overrides
         any pre-existing defaults.
 
         The section DEFAULT is special.
@@ -877,8 +878,8 @@
 
     def has_option(self, section, option):
         """Check for the existence of a given option in a given section.
-        If the specified `section' is None or an empty string, DEFAULT is
-        assumed. If the specified `section' does not exist, returns False."""
+        If the specified `section` is None or an empty string, DEFAULT is
+        assumed. If the specified `section` does not exist, returns False."""
         if not section or section == self.default_section:
             option = self.optionxform(option)
             return option in self._defaults
@@ -906,7 +907,7 @@
     def write(self, fp, space_around_delimiters=True):
         """Write an .ini-format representation of the configuration state.
 
-        If `space_around_delimiters' is True (the default), delimiters
+        If `space_around_delimiters` is True (the default), delimiters
         between keys and values are surrounded by spaces.
 
         Please note that comments in the original configuration file are not
@@ -924,7 +925,7 @@
                                 self._sections[section].items(), d)
 
     def _write_section(self, fp, section_name, section_items, delimiter):
-        """Write a single section to the specified `fp'."""
+        """Write a single section to the specified `fp`."""
         fp.write("[{}]\n".format(section_name))
         for key, value in section_items:
             value = self._interpolation.before_write(self, section_name, key,
@@ -998,8 +999,8 @@
         """Parse a sectioned configuration file.
 
         Each section in a configuration file contains a header, indicated by
-        a name in square brackets (`[]'), plus key/value options, indicated by
-        `name' and `value' delimited with a specific substring (`=' or `:' by
+        a name in square brackets (`[]`), plus key/value options, indicated by
+        `name` and `value` delimited with a specific substring (`=` or `:` by
         default).
 
         Values can span multiple lines, as long as they are indented deeper
@@ -1007,7 +1008,7 @@
         lines may be treated as parts of multiline values or ignored.
 
         Configuration files may include comments, prefixed by specific
-        characters (`#' and `;' by default). Comments may appear on their own
+        characters (`#` and `;` by default). Comments may appear on their own
         in an otherwise empty line or may be entered in lines holding values or
         section names. Please note that comments get stripped off when reading configuration files.
         """
diff --git a/common/py3-stdlib/copy.py b/common/py3-stdlib/copy.py
index 69bac98..1b276af 100644
--- a/common/py3-stdlib/copy.py
+++ b/common/py3-stdlib/copy.py
@@ -258,7 +258,7 @@
 
 def _reconstruct(x, memo, func, args,
                  state=None, listiter=None, dictiter=None,
-                 deepcopy=deepcopy):
+                 *, deepcopy=deepcopy):
     deep = memo is not None
     if deep and args:
         args = (deepcopy(arg, memo) for arg in args)
diff --git a/common/py3-stdlib/crypt.py b/common/py3-stdlib/crypt.py
index 33dbc46..b296c3e 100644
--- a/common/py3-stdlib/crypt.py
+++ b/common/py3-stdlib/crypt.py
@@ -94,7 +94,7 @@
         result = crypt('', salt)
     except OSError as e:
         # Not all libc libraries support all encryption methods.
-        if e.errno == errno.EINVAL:
+        if e.errno in {errno.EINVAL, errno.EPERM, errno.ENOSYS}:
             return False
         raise
     if result and len(result) == method.total_size:
diff --git a/common/py3-stdlib/ctypes/test/test_parameters.py b/common/py3-stdlib/ctypes/test/test_parameters.py
index 38af7ac..3fdc994 100644
--- a/common/py3-stdlib/ctypes/test/test_parameters.py
+++ b/common/py3-stdlib/ctypes/test/test_parameters.py
@@ -244,6 +244,58 @@
         self.assertRegex(repr(c_wchar_p.from_param('hihi')), r"^<cparam 'Z' \(0x[A-Fa-f0-9]+\)>$")
         self.assertRegex(repr(c_void_p.from_param(0x12)), r"^<cparam 'P' \(0x0*12\)>$")
 
+    @test.support.cpython_only
+    def test_from_param_result_refcount(self):
+        # Issue #99952
+        import _ctypes_test
+        from ctypes import PyDLL, c_int, c_void_p, py_object, Structure
+
+        class X(Structure):
+            """This struct size is <= sizeof(void*)."""
+            _fields_ = [("a", c_void_p)]
+
+            def __del__(self):
+                trace.append(4)
+
+            @classmethod
+            def from_param(cls, value):
+                trace.append(2)
+                return cls()
+
+        PyList_Append = PyDLL(_ctypes_test.__file__)._testfunc_pylist_append
+        PyList_Append.restype = c_int
+        PyList_Append.argtypes = [py_object, py_object, X]
+
+        trace = []
+        trace.append(1)
+        PyList_Append(trace, 3, "dummy")
+        trace.append(5)
+
+        self.assertEqual(trace, [1, 2, 3, 4, 5])
+
+        class Y(Structure):
+            """This struct size is > sizeof(void*)."""
+            _fields_ = [("a", c_void_p), ("b", c_void_p)]
+
+            def __del__(self):
+                trace.append(4)
+
+            @classmethod
+            def from_param(cls, value):
+                trace.append(2)
+                return cls()
+
+        PyList_Append = PyDLL(_ctypes_test.__file__)._testfunc_pylist_append
+        PyList_Append.restype = c_int
+        PyList_Append.argtypes = [py_object, py_object, Y]
+
+        trace = []
+        trace.append(1)
+        PyList_Append(trace, 3, "dummy")
+        trace.append(5)
+
+        self.assertEqual(trace, [1, 2, 3, 4, 5])
+
 ################################################################
 
 if __name__ == '__main__':
diff --git a/common/py3-stdlib/ctypes/test/test_pep3118.py b/common/py3-stdlib/ctypes/test/test_pep3118.py
index 81e8ca7..efffc80 100644
--- a/common/py3-stdlib/ctypes/test/test_pep3118.py
+++ b/common/py3-stdlib/ctypes/test/test_pep3118.py
@@ -176,7 +176,9 @@
     ## arrays and pointers
 
     (c_double * 4,              "<d",                   (4,),           c_double),
+    (c_double * 0,              "<d",                   (0,),           c_double),
     (c_float * 4 * 3 * 2,       "<f",                   (2,3,4),        c_float),
+    (c_float * 4 * 0 * 2,       "<f",                   (2,0,4),        c_float),
     (POINTER(c_short) * 2,      "&<" + s_short,         (2,),           POINTER(c_short)),
     (POINTER(c_short) * 2 * 3,  "&<" + s_short,         (3,2,),         POINTER(c_short)),
     (POINTER(c_short * 2),      "&(2)<" + s_short,      (),             POINTER(c_short)),
diff --git a/common/py3-stdlib/ctypes/test/test_refcounts.py b/common/py3-stdlib/ctypes/test/test_refcounts.py
index f2edfa6..48958cd 100644
--- a/common/py3-stdlib/ctypes/test/test_refcounts.py
+++ b/common/py3-stdlib/ctypes/test/test_refcounts.py
@@ -97,5 +97,20 @@
         f(1, 2)
         self.assertEqual(sys.getrefcount(ctypes.c_int), a)
 
+    @support.refcount_test
+    def test_callback_py_object_none_return(self):
+        # bpo-36880: test that returning None from a py_object callback
+        # does not decrement the refcount of None.
+
+        for FUNCTYPE in (ctypes.CFUNCTYPE, ctypes.PYFUNCTYPE):
+            with self.subTest(FUNCTYPE=FUNCTYPE):
+                @FUNCTYPE(ctypes.py_object)
+                def func():
+                    return None
+
+                # Check that calling func does not affect None's refcount.
+                for _ in range(10000):
+                    func()
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/common/py3-stdlib/ctypes/test/test_struct_fields.py b/common/py3-stdlib/ctypes/test/test_struct_fields.py
index ee8415f..fefeaea 100644
--- a/common/py3-stdlib/ctypes/test/test_struct_fields.py
+++ b/common/py3-stdlib/ctypes/test/test_struct_fields.py
@@ -54,6 +54,15 @@
         x.char = b'a\0b\0'
         self.assertEqual(bytes(x), b'a\x00###')
 
+    def test_gh99275(self):
+        class BrokenStructure(Structure):
+            def __init_subclass__(cls, **kwargs):
+                cls._fields_ = []  # This line will fail, `stgdict` is not ready
+
+        with self.assertRaisesRegex(TypeError,
+                                    'ctypes state is not initialized'):
+            class Subclass(BrokenStructure): ...
+
     # __set__ and __get__ should raise a TypeError in case their self
     # argument is not a ctype instance.
     def test___set__(self):
diff --git a/common/py3-stdlib/ctypes/test/test_structures.py b/common/py3-stdlib/ctypes/test/test_structures.py
index 97ad2b8..f95d5a9 100644
--- a/common/py3-stdlib/ctypes/test/test_structures.py
+++ b/common/py3-stdlib/ctypes/test/test_structures.py
@@ -332,13 +332,13 @@
         cls, msg = self.get_except(Person, b"Someone", (1, 2))
         self.assertEqual(cls, RuntimeError)
         self.assertEqual(msg,
-                             "(Phone) <class 'TypeError'>: "
+                             "(Phone) TypeError: "
                              "expected bytes, int found")
 
         cls, msg = self.get_except(Person, b"Someone", (b"a", b"b", b"c"))
         self.assertEqual(cls, RuntimeError)
         self.assertEqual(msg,
-                             "(Phone) <class 'TypeError'>: too many initializers")
+                             "(Phone) TypeError: too many initializers")
 
     def test_huge_field_name(self):
         # issue12881: segfault with large structure field names
diff --git a/common/py3-stdlib/dataclasses.py b/common/py3-stdlib/dataclasses.py
index 105a95b..1742900 100644
--- a/common/py3-stdlib/dataclasses.py
+++ b/common/py3-stdlib/dataclasses.py
@@ -222,6 +222,26 @@
 # https://bugs.python.org/issue33453 for details.
 _MODULE_IDENTIFIER_RE = re.compile(r'^(?:\s*(\w+)\s*\.)?\s*(\w+)')
 
+# This function's logic is copied from "recursive_repr" function in
+# reprlib module to avoid dependency.
+def _recursive_repr(user_function):
+    # Decorator to make a repr function return "..." for a recursive
+    # call.
+    repr_running = set()
+
+    @functools.wraps(user_function)
+    def wrapper(self):
+        key = id(self), _thread.get_ident()
+        if key in repr_running:
+            return '...'
+        repr_running.add(key)
+        try:
+            result = user_function(self)
+        finally:
+            repr_running.discard(key)
+        return result
+    return wrapper
+
 class InitVar:
     __slots__ = ('type', )
 
@@ -279,6 +299,7 @@
         self.kw_only = kw_only
         self._field_type = None
 
+    @_recursive_repr
     def __repr__(self):
         return ('Field('
                 f'name={self.name!r},'
@@ -388,36 +409,13 @@
     return f'({",".join([f"{obj_name}.{f.name}" for f in fields])},)'
 
 
-# This function's logic is copied from "recursive_repr" function in
-# reprlib module to avoid dependency.
-def _recursive_repr(user_function):
-    # Decorator to make a repr function return "..." for a recursive
-    # call.
-    repr_running = set()
-
-    @functools.wraps(user_function)
-    def wrapper(self):
-        key = id(self), _thread.get_ident()
-        if key in repr_running:
-            return '...'
-        repr_running.add(key)
-        try:
-            result = user_function(self)
-        finally:
-            repr_running.discard(key)
-        return result
-    return wrapper
-
-
 def _create_fn(name, args, body, *, globals=None, locals=None,
                return_type=MISSING):
-    # Note that we mutate locals when exec() is called.  Caller
-    # beware!  The only callers are internal to this module, so no
+    # Note that we may mutate locals. Callers beware!
+    # The only callers are internal to this module, so no
     # worries about external callers.
     if locals is None:
         locals = {}
-    if 'BUILTINS' not in locals:
-        locals['BUILTINS'] = builtins
     return_annotation = ''
     if return_type is not MISSING:
         locals['_return_type'] = return_type
@@ -443,7 +441,7 @@
     # self_name is what "self" is called in this function: don't
     # hard-code "self", since that might be a field name.
     if frozen:
-        return f'BUILTINS.object.__setattr__({self_name},{name!r},{value})'
+        return f'__dataclass_builtins_object__.__setattr__({self_name},{name!r},{value})'
     return f'{self_name}.{name}={value}'
 
 
@@ -550,6 +548,7 @@
     locals.update({
         'MISSING': MISSING,
         '_HAS_DEFAULT_FACTORY': _HAS_DEFAULT_FACTORY,
+        '__dataclass_builtins_object__': object,
     })
 
     body_lines = []
@@ -1196,7 +1195,7 @@
     try:
         fields = getattr(class_or_instance, _FIELDS)
     except AttributeError:
-        raise TypeError('must be called with a dataclass type or instance')
+        raise TypeError('must be called with a dataclass type or instance') from None
 
     # Exclude pseudo-fields.  Note that fields is sorted by insertion
     # order, so the order of the tuple is as the fields were defined.
diff --git a/common/py3-stdlib/datetime.py b/common/py3-stdlib/datetime.py
index 6bf37cc..d087c98 100644
--- a/common/py3-stdlib/datetime.py
+++ b/common/py3-stdlib/datetime.py
@@ -1652,7 +1652,7 @@
         y, m, d, hh, mm, ss, weekday, jday, dst = converter(t)
         ss = min(ss, 59)    # clamp out leap seconds if the platform has them
         result = cls(y, m, d, hh, mm, ss, us, tz)
-        if tz is None:
+        if tz is None and not utc:
             # As of version 2015f max fold in IANA database is
             # 23 hours at 1969-09-30 13:00:00 in Kwajalein.
             # Let's probe 24 hours in the past to detect a transition:
@@ -1673,7 +1673,7 @@
                 probe2 = cls(y, m, d, hh, mm, ss, us, tz)
                 if probe2 == result:
                     result._fold = 1
-        else:
+        elif tz is not None:
             result = tz.fromutc(result)
         return result
 
diff --git a/common/py3-stdlib/difflib.py b/common/py3-stdlib/difflib.py
index afd8a0c..ba0b256 100644
--- a/common/py3-stdlib/difflib.py
+++ b/common/py3-stdlib/difflib.py
@@ -837,7 +837,7 @@
         Each sequence must contain individual single-line strings ending with
         newlines. Such sequences can be obtained from the `readlines()` method
         of file-like objects.  The delta generated also consists of newline-
-        terminated strings, ready to be printed as-is via the writeline()
+        terminated strings, ready to be printed as-is via the writelines()
         method of a file-like object.
 
         Example:
diff --git a/common/py3-stdlib/doctest.py b/common/py3-stdlib/doctest.py
index b27cbdf..37b31cf 100644
--- a/common/py3-stdlib/doctest.py
+++ b/common/py3-stdlib/doctest.py
@@ -1085,19 +1085,21 @@
 
     def _find_lineno(self, obj, source_lines):
         """
-        Return a line number of the given object's docstring.  Note:
-        this method assumes that the object has a docstring.
+        Return a line number of the given object's docstring.
+
+        Returns `None` if the given object does not have a docstring.
         """
         lineno = None
+        docstring = getattr(obj, '__doc__', None)
 
         # Find the line number for modules.
-        if inspect.ismodule(obj):
+        if inspect.ismodule(obj) and docstring is not None:
             lineno = 0
 
         # Find the line number for classes.
         # Note: this could be fooled if a class is defined multiple
         # times in a single file.
-        if inspect.isclass(obj):
+        if inspect.isclass(obj) and docstring is not None:
             if source_lines is None:
                 return None
             pat = re.compile(r'^\s*class\s*%s\b' %
@@ -1109,7 +1111,9 @@
 
         # Find the line number for functions & methods.
         if inspect.ismethod(obj): obj = obj.__func__
-        if inspect.isfunction(obj): obj = obj.__code__
+        if inspect.isfunction(obj) and getattr(obj, '__doc__', None):
+            # We don't use `docstring` var here, because `obj` can be changed.
+            obj = obj.__code__
         if inspect.istraceback(obj): obj = obj.tb_frame
         if inspect.isframe(obj): obj = obj.f_code
         if inspect.iscode(obj):
@@ -2171,6 +2175,7 @@
         unittest.TestCase.__init__(self)
         self._dt_optionflags = optionflags
         self._dt_checker = checker
+        self._dt_globs = test.globs.copy()
         self._dt_test = test
         self._dt_setUp = setUp
         self._dt_tearDown = tearDown
@@ -2187,7 +2192,9 @@
         if self._dt_tearDown is not None:
             self._dt_tearDown(test)
 
+        # restore the original globs
         test.globs.clear()
+        test.globs.update(self._dt_globs)
 
     def runTest(self):
         test = self._dt_test
diff --git a/common/py3-stdlib/email/_encoded_words.py b/common/py3-stdlib/email/_encoded_words.py
index 295ae7e..6795a60 100644
--- a/common/py3-stdlib/email/_encoded_words.py
+++ b/common/py3-stdlib/email/_encoded_words.py
@@ -179,15 +179,15 @@
     # Turn the CTE decoded bytes into unicode.
     try:
         string = bstring.decode(charset)
-    except UnicodeError:
+    except UnicodeDecodeError:
         defects.append(errors.UndecodableBytesDefect("Encoded word "
-            "contains bytes not decodable using {} charset".format(charset)))
+            f"contains bytes not decodable using {charset!r} charset"))
         string = bstring.decode(charset, 'surrogateescape')
-    except LookupError:
+    except (LookupError, UnicodeEncodeError):
         string = bstring.decode('ascii', 'surrogateescape')
         if charset.lower() != 'unknown-8bit':
-            defects.append(errors.CharsetError("Unknown charset {} "
-                "in encoded word; decoded as unknown bytes".format(charset)))
+            defects.append(errors.CharsetError(f"Unknown charset {charset!r} "
+                f"in encoded word; decoded as unknown bytes"))
     return string, charset, lang, defects
 
 
diff --git a/common/py3-stdlib/email/_header_value_parser.py b/common/py3-stdlib/email/_header_value_parser.py
index 51d355f..e637e6d 100644
--- a/common/py3-stdlib/email/_header_value_parser.py
+++ b/common/py3-stdlib/email/_header_value_parser.py
@@ -781,7 +781,7 @@
                     else:
                         try:
                             value = value.decode(charset, 'surrogateescape')
-                        except LookupError:
+                        except (LookupError, UnicodeEncodeError):
                             # XXX: there should really be a custom defect for
                             # unknown character set to make it easy to find,
                             # because otherwise unknown charset is a silent
@@ -2379,7 +2379,7 @@
         digits += value[0]
         value = value[1:]
     if digits[0] == '0' and digits != '0':
-        section.defects.append(errors.InvalidHeaderError(
+        section.defects.append(errors.InvalidHeaderDefect(
                 "section number has an invalid leading 0"))
     section.number = int(digits)
     section.append(ValueTerminal(digits, 'digits'))
diff --git a/common/py3-stdlib/email/_parseaddr.py b/common/py3-stdlib/email/_parseaddr.py
index ba5ad5a..febe411 100644
--- a/common/py3-stdlib/email/_parseaddr.py
+++ b/common/py3-stdlib/email/_parseaddr.py
@@ -95,6 +95,8 @@
         return None
     data = data[:5]
     [dd, mm, yy, tm, tz] = data
+    if not (dd and mm and yy):
+        return None
     mm = mm.lower()
     if mm not in _monthnames:
         dd, mm = mm, dd.lower()
@@ -110,6 +112,8 @@
         yy, tm = tm, yy
     if yy[-1] == ',':
         yy = yy[:-1]
+        if not yy:
+            return None
     if not yy[0].isdigit():
         yy, tz = tz, yy
     if tm[-1] == ',':
diff --git a/common/py3-stdlib/email/charset.py b/common/py3-stdlib/email/charset.py
index d3d759a..791b658 100644
--- a/common/py3-stdlib/email/charset.py
+++ b/common/py3-stdlib/email/charset.py
@@ -112,8 +112,8 @@
     charset is the input character set, and must be the canonical name of a
     character set.
 
-    Optional header_enc and body_enc is either Charset.QP for
-    quoted-printable, Charset.BASE64 for base64 encoding, Charset.SHORTEST for
+    Optional header_enc and body_enc is either charset.QP for
+    quoted-printable, charset.BASE64 for base64 encoding, charset.SHORTEST for
     the shortest of qp or base64 encoding, or None for no encoding.  SHORTEST
     is only valid for header_enc.  It describes how message headers and
     message bodies in the input charset are to be encoded.  Default is no
@@ -185,13 +185,13 @@
 
     header_encoding: If the character set must be encoded before it can be
                      used in an email header, this attribute will be set to
-                     Charset.QP (for quoted-printable), Charset.BASE64 (for
-                     base64 encoding), or Charset.SHORTEST for the shortest of
+                     charset.QP (for quoted-printable), charset.BASE64 (for
+                     base64 encoding), or charset.SHORTEST for the shortest of
                      QP or BASE64 encoding.  Otherwise, it will be None.
 
     body_encoding: Same as header_encoding, but describes the encoding for the
                    mail message's body, which indeed may be different than the
-                   header encoding.  Charset.SHORTEST is not allowed for
+                   header encoding.  charset.SHORTEST is not allowed for
                    body_encoding.
 
     output_charset: Some character sets must be converted before they can be
diff --git a/common/py3-stdlib/email/mime/application.py b/common/py3-stdlib/email/mime/application.py
index 6877e55..f67cbad 100644
--- a/common/py3-stdlib/email/mime/application.py
+++ b/common/py3-stdlib/email/mime/application.py
@@ -17,7 +17,7 @@
                  _encoder=encoders.encode_base64, *, policy=None, **_params):
         """Create an application/* type MIME document.
 
-        _data is a string containing the raw application data.
+        _data contains the bytes for the raw application data.
 
         _subtype is the MIME content type subtype, defaulting to
         'octet-stream'.
diff --git a/common/py3-stdlib/email/mime/audio.py b/common/py3-stdlib/email/mime/audio.py
index 4bcd7b2..7cca3f9 100644
--- a/common/py3-stdlib/email/mime/audio.py
+++ b/common/py3-stdlib/email/mime/audio.py
@@ -46,7 +46,7 @@
                  _encoder=encoders.encode_base64, *, policy=None, **_params):
         """Create an audio/* type MIME document.
 
-        _audiodata is a string containing the raw audio data.  If this data
+        _audiodata contains the bytes for the raw audio data.  If this data
         can be decoded by the standard Python `sndhdr' module, then the
         subtype will be automatically included in the Content-Type header.
         Otherwise, you can specify  the specific audio subtype via the
diff --git a/common/py3-stdlib/email/mime/image.py b/common/py3-stdlib/email/mime/image.py
index 9272464..6dc7ec4 100644
--- a/common/py3-stdlib/email/mime/image.py
+++ b/common/py3-stdlib/email/mime/image.py
@@ -20,7 +20,7 @@
                  _encoder=encoders.encode_base64, *, policy=None, **_params):
         """Create an image/* type MIME document.
 
-        _imagedata is a string containing the raw image data.  If this data
+        _imagedata contains the bytes for the raw image data.  If the data
         can be decoded by the standard Python `imghdr' module, then the
         subtype will be automatically included in the Content-Type header.
         Otherwise, you can specify the specific image subtype via the _subtype
diff --git a/common/py3-stdlib/encodings/idna.py b/common/py3-stdlib/encodings/idna.py
index ea40585..bf98f51 100644
--- a/common/py3-stdlib/encodings/idna.py
+++ b/common/py3-stdlib/encodings/idna.py
@@ -39,23 +39,21 @@
 
     # Check bidi
     RandAL = [stringprep.in_table_d1(x) for x in label]
-    for c in RandAL:
-        if c:
-            # There is a RandAL char in the string. Must perform further
-            # tests:
-            # 1) The characters in section 5.8 MUST be prohibited.
-            # This is table C.8, which was already checked
-            # 2) If a string contains any RandALCat character, the string
-            # MUST NOT contain any LCat character.
-            if any(stringprep.in_table_d2(x) for x in label):
-                raise UnicodeError("Violation of BIDI requirement 2")
-
-            # 3) If a string contains any RandALCat character, a
-            # RandALCat character MUST be the first character of the
-            # string, and a RandALCat character MUST be the last
-            # character of the string.
-            if not RandAL[0] or not RandAL[-1]:
-                raise UnicodeError("Violation of BIDI requirement 3")
+    if any(RandAL):
+        # There is a RandAL char in the string. Must perform further
+        # tests:
+        # 1) The characters in section 5.8 MUST be prohibited.
+        # This is table C.8, which was already checked
+        # 2) If a string contains any RandALCat character, the string
+        # MUST NOT contain any LCat character.
+        if any(stringprep.in_table_d2(x) for x in label):
+            raise UnicodeError("Violation of BIDI requirement 2")
+        # 3) If a string contains any RandALCat character, a
+        # RandALCat character MUST be the first character of the
+        # string, and a RandALCat character MUST be the last
+        # character of the string.
+        if not RandAL[0] or not RandAL[-1]:
+            raise UnicodeError("Violation of BIDI requirement 3")
 
     return label
 
diff --git a/common/py3-stdlib/fileinput.py b/common/py3-stdlib/fileinput.py
index 3534718..3bd1990 100644
--- a/common/py3-stdlib/fileinput.py
+++ b/common/py3-stdlib/fileinput.py
@@ -355,18 +355,21 @@
                     pass
                 # The next few lines may raise OSError
                 os.rename(self._filename, self._backupfilename)
-                self._file = open(self._backupfilename, self._mode, encoding=encoding)
+                self._file = open(self._backupfilename, self._mode,
+                                  encoding=encoding, errors=self._errors)
                 try:
                     perm = os.fstat(self._file.fileno()).st_mode
                 except OSError:
-                    self._output = open(self._filename, self._write_mode, encoding=encoding)
+                    self._output = open(self._filename, self._write_mode,
+                                        encoding=encoding, errors=self._errors)
                 else:
                     mode = os.O_CREAT | os.O_WRONLY | os.O_TRUNC
                     if hasattr(os, 'O_BINARY'):
                         mode |= os.O_BINARY
 
                     fd = os.open(self._filename, mode, perm)
-                    self._output = os.fdopen(fd, self._write_mode, encoding=encoding)
+                    self._output = os.fdopen(fd, self._write_mode,
+                                             encoding=encoding, errors=self._errors)
                     try:
                         os.chmod(self._filename, perm)
                     except OSError:
@@ -416,7 +419,7 @@
 
 
 def hook_compressed(filename, mode, *, encoding=None, errors=None):
-    if encoding is None:  # EncodingWarning is emitted in FileInput() already.
+    if encoding is None and "b" not in mode:  # EncodingWarning is emitted in FileInput() already.
         encoding = "locale"
     ext = os.path.splitext(filename)[1]
     if ext == '.gz':
diff --git a/common/py3-stdlib/fnmatch.py b/common/py3-stdlib/fnmatch.py
index 7c52c23..fee59bf 100644
--- a/common/py3-stdlib/fnmatch.py
+++ b/common/py3-stdlib/fnmatch.py
@@ -108,7 +108,7 @@
                 add('\\[')
             else:
                 stuff = pat[i:j]
-                if '--' not in stuff:
+                if '-' not in stuff:
                     stuff = stuff.replace('\\', r'\\')
                 else:
                     chunks = []
@@ -120,7 +120,16 @@
                         chunks.append(pat[i:k])
                         i = k+1
                         k = k+3
-                    chunks.append(pat[i:j])
+                    chunk = pat[i:j]
+                    if chunk:
+                        chunks.append(chunk)
+                    else:
+                        chunks[-1] += '-'
+                    # Remove empty ranges -- invalid in RE.
+                    for k in range(len(chunks)-1, 0, -1):
+                        if chunks[k-1][-1] > chunks[k][0]:
+                            chunks[k-1] = chunks[k-1][:-1] + chunks[k][1:]
+                            del chunks[k]
                     # Escape backslashes and hyphens for set difference (--).
                     # Hyphens that create ranges shouldn't be escaped.
                     stuff = '-'.join(s.replace('\\', r'\\').replace('-', r'\-')
@@ -128,11 +137,18 @@
                 # Escape set operations (&&, ~~ and ||).
                 stuff = re.sub(r'([&~|])', r'\\\1', stuff)
                 i = j+1
-                if stuff[0] == '!':
-                    stuff = '^' + stuff[1:]
-                elif stuff[0] in ('^', '['):
-                    stuff = '\\' + stuff
-                add(f'[{stuff}]')
+                if not stuff:
+                    # Empty range: never match.
+                    add('(?!)')
+                elif stuff == '!':
+                    # Negated empty range: match any character.
+                    add('.')
+                else:
+                    if stuff[0] == '!':
+                        stuff = '^' + stuff[1:]
+                    elif stuff[0] in ('^', '['):
+                        stuff = '\\' + stuff
+                    add(f'[{stuff}]')
         else:
             add(re.escape(c))
     assert i == n
diff --git a/common/py3-stdlib/html/__init__.py b/common/py3-stdlib/html/__init__.py
index da0a0a3..1543460 100644
--- a/common/py3-stdlib/html/__init__.py
+++ b/common/py3-stdlib/html/__init__.py
@@ -25,7 +25,7 @@
     return s
 
 
-# see http://www.w3.org/TR/html5/syntax.html#tokenizing-character-references
+# see https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state
 
 _invalid_charrefs = {
     0x00: '\ufffd',  # REPLACEMENT CHARACTER
diff --git a/common/py3-stdlib/html/entities.py b/common/py3-stdlib/html/entities.py
index 91ea5da..dc50863 100644
--- a/common/py3-stdlib/html/entities.py
+++ b/common/py3-stdlib/html/entities.py
@@ -4,6 +4,7 @@
 
 
 # maps the HTML entity name to the Unicode code point
+# from https://html.spec.whatwg.org/multipage/named-characters.html
 name2codepoint = {
     'AElig':    0x00c6, # latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1
     'Aacute':   0x00c1, # latin capital letter A with acute, U+00C1 ISOlat1
diff --git a/common/py3-stdlib/http/client.py b/common/py3-stdlib/http/client.py
index a6ab135..d1b7b10 100644
--- a/common/py3-stdlib/http/client.py
+++ b/common/py3-stdlib/http/client.py
@@ -448,6 +448,7 @@
         return self.fp is None
 
     def read(self, amt=None):
+        """Read and return the response body, or up to the next amt bytes."""
         if self.fp is None:
             return b""
 
@@ -942,7 +943,7 @@
             (self.host,self.port), self.timeout, self.source_address)
         # Might fail in OSs that don't implement TCP_NODELAY
         try:
-             self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
+            self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
         except OSError as e:
             if e.errno != errno.ENOPROTOOPT:
                 raise
diff --git a/common/py3-stdlib/http/cookiejar.py b/common/py3-stdlib/http/cookiejar.py
index eaa76c2..0380d9f 100644
--- a/common/py3-stdlib/http/cookiejar.py
+++ b/common/py3-stdlib/http/cookiejar.py
@@ -1990,7 +1990,7 @@
 
     This class differs from CookieJar only in the format it uses to save and
     load cookies to and from a file.  This class uses the Mozilla/Netscape
-    `cookies.txt' format.  lynx uses this file format, too.
+    `cookies.txt' format.  curl and lynx use this file format, too.
 
     Don't expect cookies saved while the browser is running to be noticed by
     the browser (in fact, Mozilla on unix will overwrite your saved cookies if
diff --git a/common/py3-stdlib/http/server.py b/common/py3-stdlib/http/server.py
index 58abadf..9c218d0 100644
--- a/common/py3-stdlib/http/server.py
+++ b/common/py3-stdlib/http/server.py
@@ -93,6 +93,7 @@
 import html
 import http.client
 import io
+import itertools
 import mimetypes
 import os
 import posixpath
@@ -330,6 +331,13 @@
                 return False
         self.command, self.path = command, path
 
+        # gh-87389: The purpose of replacing '//' with '/' is to protect
+        # against open redirect attacks possibly triggered if the path starts
+        # with '//' because http clients treat //path as an absolute URI
+        # without scheme (similar to http://path) rather than a path.
+        if self.path.startswith('//'):
+            self.path = '/' + self.path.lstrip('/')  # Reduce to a single /
+
         # Examine the headers and look for a Connection directive.
         try:
             self.headers = http.client.parse_headers(self.rfile,
@@ -556,6 +564,11 @@
 
         self.log_message(format, *args)
 
+    # https://en.wikipedia.org/wiki/List_of_Unicode_characters#Control_codes
+    _control_char_table = str.maketrans(
+            {c: fr'\x{c:02x}' for c in itertools.chain(range(0x20), range(0x7f,0xa0))})
+    _control_char_table[ord('\\')] = r'\\'
+
     def log_message(self, format, *args):
         """Log an arbitrary message.
 
@@ -571,12 +584,16 @@
         The client ip and current date/time are prefixed to
         every message.
 
+        Unicode control characters are replaced with escaped hex
+        before writing the output to stderr.
+
         """
 
+        message = format % args
         sys.stderr.write("%s - - [%s] %s\n" %
                          (self.address_string(),
                           self.log_date_time_string(),
-                          format%args))
+                          message.translate(self._control_char_table)))
 
     def version_string(self):
         """Return the server software version string."""
@@ -692,7 +709,7 @@
                 return None
             for index in "index.html", "index.htm":
                 index = os.path.join(path, index)
-                if os.path.exists(index):
+                if os.path.isfile(index):
                     path = index
                     break
             else:
diff --git a/common/py3-stdlib/importlib/_common.py b/common/py3-stdlib/importlib/_common.py
index 549fee3..84144c0 100644
--- a/common/py3-stdlib/importlib/_common.py
+++ b/common/py3-stdlib/importlib/_common.py
@@ -80,7 +80,10 @@
 
 
 @contextlib.contextmanager
-def _tempfile(reader, suffix=''):
+def _tempfile(reader, suffix='',
+              # gh-93353: Keep a reference to call os.remove() in late Python
+              # finalization.
+              *, _os_remove=os.remove):
     # Not using tempfile.NamedTemporaryFile as it leads to deeper 'try'
     # blocks due to the need to close the temporary file to work on Windows
     # properly.
@@ -92,7 +95,7 @@
         yield pathlib.Path(raw_path)
     finally:
         try:
-            os.remove(raw_path)
+            _os_remove(raw_path)
         except FileNotFoundError:
             pass
 
diff --git a/common/py3-stdlib/importlib/metadata/__init__.py b/common/py3-stdlib/importlib/metadata/__init__.py
index b3063cd..682067d 100644
--- a/common/py3-stdlib/importlib/metadata/__init__.py
+++ b/common/py3-stdlib/importlib/metadata/__init__.py
@@ -17,7 +17,7 @@
 from . import _adapters, _meta
 from ._meta import PackageMetadata
 from ._collections import FreezableDefaultDict, Pair
-from ._functools import method_cache
+from ._functools import method_cache, pass_none
 from ._itertools import unique_everseen
 from ._meta import PackageMetadata, SimplePath
 
@@ -938,13 +938,25 @@
         normalized name from the file system path.
         """
         stem = os.path.basename(str(self._path))
-        return self._name_from_stem(stem) or super()._normalized_name
+        return (
+            pass_none(Prepared.normalize)(self._name_from_stem(stem))
+            or super()._normalized_name
+        )
 
-    def _name_from_stem(self, stem):
-        name, ext = os.path.splitext(stem)
+    @staticmethod
+    def _name_from_stem(stem):
+        """
+        >>> PathDistribution._name_from_stem('foo-3.0.egg-info')
+        'foo'
+        >>> PathDistribution._name_from_stem('CherryPy-3.0.dist-info')
+        'CherryPy'
+        >>> PathDistribution._name_from_stem('face.egg-info')
+        'face'
+        """
+        filename, ext = os.path.splitext(stem)
         if ext not in ('.dist-info', '.egg-info'):
             return
-        name, sep, rest = stem.partition('-')
+        name, sep, rest = filename.partition('-')
         return name
 
 
diff --git a/common/py3-stdlib/importlib/metadata/_functools.py b/common/py3-stdlib/importlib/metadata/_functools.py
index 73f50d0..71f66bd 100644
--- a/common/py3-stdlib/importlib/metadata/_functools.py
+++ b/common/py3-stdlib/importlib/metadata/_functools.py
@@ -83,3 +83,22 @@
     wrapper.cache_clear = lambda: None
 
     return wrapper
+
+
+# From jaraco.functools 3.3
+def pass_none(func):
+    """
+    Wrap func so it's not called if its first param is None
+
+    >>> print_text = pass_none(print)
+    >>> print_text('text')
+    text
+    >>> print_text(None)
+    """
+
+    @functools.wraps(func)
+    def wrapper(param, *args, **kwargs):
+        if param is not None:
+            return func(param, *args, **kwargs)
+
+    return wrapper
diff --git a/common/py3-stdlib/inspect.py b/common/py3-stdlib/inspect.py
index c5881cc..2999a60 100644
--- a/common/py3-stdlib/inspect.py
+++ b/common/py3-stdlib/inspect.py
@@ -294,7 +294,7 @@
     while ismethod(f):
         f = f.__func__
     f = functools._unwrap_partial(f)
-    if not isfunction(f):
+    if not (isfunction(f) or _signature_is_functionlike(f)):
         return False
     return bool(f.__code__.co_flags & flag)
 
@@ -1052,7 +1052,6 @@
         self.started = False
         self.passline = False
         self.indecorator = False
-        self.decoratorhasargs = False
         self.last = 1
         self.body_col0 = None
 
@@ -1067,13 +1066,6 @@
                     self.islambda = True
                 self.started = True
             self.passline = True    # skip to the end of the line
-        elif token == "(":
-            if self.indecorator:
-                self.decoratorhasargs = True
-        elif token == ")":
-            if self.indecorator:
-                self.indecorator = False
-                self.decoratorhasargs = False
         elif type == tokenize.NEWLINE:
             self.passline = False   # stop skipping when a NEWLINE is seen
             self.last = srowcol[0]
@@ -1081,7 +1073,7 @@
                 raise EndOfBlock
             # hitting a NEWLINE when in a decorator without args
             # ends the decorator
-            if self.indecorator and not self.decoratorhasargs:
+            if self.indecorator:
                 self.indecorator = False
         elif self.passline:
             pass
@@ -1356,7 +1348,10 @@
 
 def formatannotation(annotation, base_module=None):
     if getattr(annotation, '__module__', None) == 'typing':
-        return repr(annotation).replace('typing.', '')
+        def repl(match):
+            text = match.group()
+            return text.removeprefix('typing.')
+        return re.sub(r'[\w\.]+', repl, repr(annotation))
     if isinstance(annotation, types.GenericAlias):
         return str(annotation)
     if isinstance(annotation, type):
@@ -2066,7 +2061,7 @@
     self_parameter = None
     last_positional_only = None
 
-    lines = [l.encode('ascii') for l in signature.split('\n')]
+    lines = [l.encode('ascii') for l in signature.split('\n') if l]
     generator = iter(lines).__next__
     token_stream = tokenize.tokenize(generator)
 
@@ -2146,7 +2141,6 @@
 
     parameters = []
     empty = Parameter.empty
-    invalid = object()
 
     module = None
     module_dict = {}
@@ -2170,11 +2164,11 @@
             try:
                 value = eval(s, sys_module_dict)
             except NameError:
-                raise RuntimeError()
+                raise ValueError
 
         if isinstance(value, (str, int, float, bytes, bool, type(None))):
             return ast.Constant(value)
-        raise RuntimeError()
+        raise ValueError
 
     class RewriteSymbolics(ast.NodeTransformer):
         def visit_Attribute(self, node):
@@ -2184,7 +2178,7 @@
                 a.append(n.attr)
                 n = n.value
             if not isinstance(n, ast.Name):
-                raise RuntimeError()
+                raise ValueError
             a.append(n.id)
             value = ".".join(reversed(a))
             return wrap_value(value)
@@ -2194,19 +2188,29 @@
                 raise ValueError()
             return wrap_value(node.id)
 
+        def visit_BinOp(self, node):
+            # Support constant folding of a couple simple binary operations
+            # commonly used to define default values in text signatures
+            left = self.visit(node.left)
+            right = self.visit(node.right)
+            if not isinstance(left, ast.Constant) or not isinstance(right, ast.Constant):
+                raise ValueError
+            if isinstance(node.op, ast.Add):
+                return ast.Constant(left.value + right.value)
+            elif isinstance(node.op, ast.Sub):
+                return ast.Constant(left.value - right.value)
+            elif isinstance(node.op, ast.BitOr):
+                return ast.Constant(left.value | right.value)
+            raise ValueError
+
     def p(name_node, default_node, default=empty):
         name = parse_name(name_node)
-        if name is invalid:
-            return None
         if default_node and default_node is not _empty:
             try:
                 default_node = RewriteSymbolics().visit(default_node)
-                o = ast.literal_eval(default_node)
+                default = ast.literal_eval(default_node)
             except ValueError:
-                o = invalid
-            if o is invalid:
-                return None
-            default = o if o is not invalid else default
+                raise ValueError("{!r} builtin has invalid signature".format(obj)) from None
         parameters.append(Parameter(name, kind, default=default, annotation=empty))
 
     # non-keyword-only parameters
@@ -2403,7 +2407,10 @@
 
     # Was this function wrapped by a decorator?
     if follow_wrapper_chains:
-        obj = unwrap(obj, stop=(lambda f: hasattr(f, "__signature__")))
+        # Unwrap until we find an explicit signature or a MethodType (which will be
+        # handled explicitly below).
+        obj = unwrap(obj, stop=(lambda f: hasattr(f, "__signature__")
+                                or isinstance(f, types.MethodType)))
         if isinstance(obj, types.MethodType):
             # If the unwrapped object is a *method*, we might want to
             # skip its first parameter (self).
diff --git a/common/py3-stdlib/ipaddress.py b/common/py3-stdlib/ipaddress.py
index 4a6496a..756f1bc 100644
--- a/common/py3-stdlib/ipaddress.py
+++ b/common/py3-stdlib/ipaddress.py
@@ -51,8 +51,7 @@
     except (AddressValueError, NetmaskValueError):
         pass
 
-    raise ValueError('%r does not appear to be an IPv4 or IPv6 address' %
-                     address)
+    raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 address')
 
 
 def ip_network(address, strict=True):
@@ -81,8 +80,7 @@
     except (AddressValueError, NetmaskValueError):
         pass
 
-    raise ValueError('%r does not appear to be an IPv4 or IPv6 network' %
-                     address)
+    raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 network')
 
 
 def ip_interface(address):
@@ -116,8 +114,7 @@
     except (AddressValueError, NetmaskValueError):
         pass
 
-    raise ValueError('%r does not appear to be an IPv4 or IPv6 interface' %
-                     address)
+    raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 interface')
 
 
 def v4_int_to_packed(address):
@@ -160,7 +157,7 @@
     """Helper to split the netmask and raise AddressValueError if needed"""
     addr = str(address).split('/')
     if len(addr) > 2:
-        raise AddressValueError("Only one '/' permitted in %r" % address)
+        raise AddressValueError(f"Only one '/' permitted in {address!r}")
     return addr
 
 
@@ -1304,7 +1301,7 @@
         # which converts into a formatted IP string.
         addr_str = str(address)
         if '/' in addr_str:
-            raise AddressValueError("Unexpected '/' in %r" % address)
+            raise AddressValueError(f"Unexpected '/' in {address!r}")
         self._ip = self._ip_int_from_string(addr_str)
 
     @property
@@ -1913,7 +1910,7 @@
         # which converts into a formatted IP string.
         addr_str = str(address)
         if '/' in addr_str:
-            raise AddressValueError("Unexpected '/' in %r" % address)
+            raise AddressValueError(f"Unexpected '/' in {address!r}")
         addr_str, self._scope_id = self._split_scope_id(addr_str)
 
         self._ip = self._ip_int_from_string(addr_str)
diff --git a/common/py3-stdlib/json/__init__.py b/common/py3-stdlib/json/__init__.py
index e4c21da..ed2c747 100644
--- a/common/py3-stdlib/json/__init__.py
+++ b/common/py3-stdlib/json/__init__.py
@@ -1,4 +1,4 @@
-r"""JSON (JavaScript Object Notation) <http://json.org> is a subset of
+r"""JSON (JavaScript Object Notation) <https://json.org> is a subset of
 JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data
 interchange format.
 
diff --git a/common/py3-stdlib/json/decoder.py b/common/py3-stdlib/json/decoder.py
index d7d8244..c5d9ae2 100644
--- a/common/py3-stdlib/json/decoder.py
+++ b/common/py3-stdlib/json/decoder.py
@@ -252,7 +252,7 @@
 
 
 class JSONDecoder(object):
-    """Simple JSON <http://json.org> decoder
+    """Simple JSON <https://json.org> decoder
 
     Performs the following translations in decoding by default:
 
diff --git a/common/py3-stdlib/json/encoder.py b/common/py3-stdlib/json/encoder.py
index 21bff2c..687c506 100644
--- a/common/py3-stdlib/json/encoder.py
+++ b/common/py3-stdlib/json/encoder.py
@@ -71,7 +71,7 @@
     c_encode_basestring_ascii or py_encode_basestring_ascii)
 
 class JSONEncoder(object):
-    """Extensible JSON <http://json.org> encoder for Python data structures.
+    """Extensible JSON <https://json.org> encoder for Python data structures.
 
     Supports the following objects and types by default:
 
diff --git a/common/py3-stdlib/linecache.py b/common/py3-stdlib/linecache.py
index 23191d6..97644a8 100644
--- a/common/py3-stdlib/linecache.py
+++ b/common/py3-stdlib/linecache.py
@@ -135,7 +135,7 @@
     try:
         with tokenize.open(fullname) as fp:
             lines = fp.readlines()
-    except OSError:
+    except (OSError, UnicodeDecodeError, SyntaxError):
         return []
     if lines and not lines[-1].endswith('\n'):
         lines[-1] += '\n'
diff --git a/common/py3-stdlib/logging/__init__.py b/common/py3-stdlib/logging/__init__.py
index 19bd2bc..d1d4333 100644
--- a/common/py3-stdlib/logging/__init__.py
+++ b/common/py3-stdlib/logging/__init__.py
@@ -325,7 +325,7 @@
         self.lineno = lineno
         self.funcName = func
         self.created = ct
-        self.msecs = (ct - int(ct)) * 1000
+        self.msecs = int((ct - int(ct)) * 1000) + 0.0  # see gh-89047
         self.relativeCreated = (self.created - _startTime) * 1000
         if logThreads:
             self.thread = threading.get_ident()
@@ -487,7 +487,7 @@
 
     def usesTime(self):
         fmt = self._fmt
-        return fmt.find('$asctime') >= 0 or fmt.find(self.asctime_format) >= 0
+        return fmt.find('$asctime') >= 0 or fmt.find(self.asctime_search) >= 0
 
     def validate(self):
         pattern = Template.pattern
diff --git a/common/py3-stdlib/logging/config.py b/common/py3-stdlib/logging/config.py
index 3bc63b7..5cab008 100644
--- a/common/py3-stdlib/logging/config.py
+++ b/common/py3-stdlib/logging/config.py
@@ -794,6 +794,7 @@
         """Configure a non-root logger from a dictionary."""
         logger = logging.getLogger(name)
         self.common_logger_config(logger, config, incremental)
+        logger.disabled = False
         propagate = config.get('propagate', None)
         if propagate is not None:
             logger.propagate = propagate
diff --git a/common/py3-stdlib/logging/handlers.py b/common/py3-stdlib/logging/handlers.py
index 61a3995..f0fdeda 100644
--- a/common/py3-stdlib/logging/handlers.py
+++ b/common/py3-stdlib/logging/handlers.py
@@ -348,11 +348,15 @@
         record is not used, as we are just comparing times, but it is needed so
         the method signatures are the same
         """
-        # See bpo-45401: Never rollover anything other than regular files
-        if os.path.exists(self.baseFilename) and not os.path.isfile(self.baseFilename):
-            return False
         t = int(time.time())
         if t >= self.rolloverAt:
+            # See #89564: Never rollover anything other than regular files
+            if os.path.exists(self.baseFilename) and not os.path.isfile(self.baseFilename):
+                # The file is not a regular file, so do not rollover, but do
+                # set the next rollover time to avoid repeated checks.
+                self.rolloverAt = self.computeRollover(t)
+                return False
+
             return True
         return False
 
@@ -1094,7 +1098,16 @@
                 dllname = os.path.join(dllname[0], r'win32service.pyd')
             self.dllname = dllname
             self.logtype = logtype
-            self._welu.AddSourceToRegistry(appname, dllname, logtype)
+            # Administrative privileges are required to add a source to the registry.
+            # This may not be available for a user that just wants to add to an
+            # existing source - handle this specific case.
+            try:
+                self._welu.AddSourceToRegistry(appname, dllname, logtype)
+            except Exception as e:
+                # This will probably be a pywintypes.error. Only raise if it's not
+                # an "access denied" error, else let it pass
+                if getattr(e, 'winerror', None) != 5:  # not access denied
+                    raise
             self.deftype = win32evtlog.EVENTLOG_ERROR_TYPE
             self.typemap = {
                 logging.DEBUG   : win32evtlog.EVENTLOG_INFORMATION_TYPE,
@@ -1439,7 +1452,7 @@
         # (if there's exception data), and also returns the formatted
         # message. We can then use this to replace the original
         # msg + args, as these might be unpickleable. We also zap the
-        # exc_info and exc_text attributes, as they are no longer
+        # exc_info, exc_text and stack_info attributes, as they are no longer
         # needed and, if not None, will typically not be pickleable.
         msg = self.format(record)
         # bpo-35726: make copy of record to avoid affecting other handlers in the chain.
@@ -1449,6 +1462,7 @@
         record.args = None
         record.exc_info = None
         record.exc_text = None
+        record.stack_info = None
         return record
 
     def emit(self, record):
diff --git a/common/py3-stdlib/mailcap.py b/common/py3-stdlib/mailcap.py
index ae416a8..444c640 100644
--- a/common/py3-stdlib/mailcap.py
+++ b/common/py3-stdlib/mailcap.py
@@ -2,6 +2,7 @@
 
 import os
 import warnings
+import re
 
 __all__ = ["getcaps","findmatch"]
 
@@ -13,6 +14,11 @@
     else:
         return 1, 0
 
+_find_unsafe = re.compile(r'[^\xa1-\U0010FFFF\w@+=:,./-]').search
+
+class UnsafeMailcapInput(Warning):
+    """Warning raised when refusing unsafe input"""
+
 
 # Part 1: top-level interface.
 
@@ -165,15 +171,22 @@
     entry to use.
 
     """
+    if _find_unsafe(filename):
+        msg = "Refusing to use mailcap with filename %r. Use a safe temporary filename." % (filename,)
+        warnings.warn(msg, UnsafeMailcapInput)
+        return None, None
     entries = lookup(caps, MIMEtype, key)
     # XXX This code should somehow check for the needsterminal flag.
     for e in entries:
         if 'test' in e:
             test = subst(e['test'], filename, plist)
+            if test is None:
+                continue
             if test and os.system(test) != 0:
                 continue
         command = subst(e[key], MIMEtype, filename, plist)
-        return command, e
+        if command is not None:
+            return command, e
     return None, None
 
 def lookup(caps, MIMEtype, key=None):
@@ -206,6 +219,10 @@
             elif c == 's':
                 res = res + filename
             elif c == 't':
+                if _find_unsafe(MIMEtype):
+                    msg = "Refusing to substitute MIME type %r into a shell command." % (MIMEtype,)
+                    warnings.warn(msg, UnsafeMailcapInput)
+                    return None
                 res = res + MIMEtype
             elif c == '{':
                 start = i
@@ -213,7 +230,12 @@
                     i = i+1
                 name = field[start:i]
                 i = i+1
-                res = res + findparam(name, plist)
+                param = findparam(name, plist)
+                if _find_unsafe(param):
+                    msg = "Refusing to substitute parameter %r (%s) into a shell command" % (param, name)
+                    warnings.warn(msg, UnsafeMailcapInput)
+                    return None
+                res = res + param
             # XXX To do:
             # %n == number of parts if type is multipart/*
             # %F == list of alternating type and filename for parts
diff --git a/common/py3-stdlib/multiprocessing/connection.py b/common/py3-stdlib/multiprocessing/connection.py
index 510e4b5..8e2facf 100644
--- a/common/py3-stdlib/multiprocessing/connection.py
+++ b/common/py3-stdlib/multiprocessing/connection.py
@@ -73,11 +73,6 @@
     if family == 'AF_INET':
         return ('localhost', 0)
     elif family == 'AF_UNIX':
-        # Prefer abstract sockets if possible to avoid problems with the address
-        # size.  When coding portable applications, some implementations have
-        # sun_path as short as 92 bytes in the sockaddr_un struct.
-        if util.abstract_sockets_supported:
-            return f"\0listener-{os.getpid()}-{next(_mmap_counter)}"
         return tempfile.mktemp(prefix='listener-', dir=util.get_temp_dir())
     elif family == 'AF_PIPE':
         return tempfile.mktemp(prefix=r'\\.\pipe\pyc-%d-%d-' %
diff --git a/common/py3-stdlib/multiprocessing/context.py b/common/py3-stdlib/multiprocessing/context.py
index 8d0525d..b1960ea 100644
--- a/common/py3-stdlib/multiprocessing/context.py
+++ b/common/py3-stdlib/multiprocessing/context.py
@@ -223,6 +223,10 @@
     def _Popen(process_obj):
         return _default_context.get_context().Process._Popen(process_obj)
 
+    @staticmethod
+    def _after_fork():
+        return _default_context.get_context().Process._after_fork()
+
 class DefaultContext(BaseContext):
     Process = Process
 
@@ -283,6 +287,11 @@
             from .popen_spawn_posix import Popen
             return Popen(process_obj)
 
+        @staticmethod
+        def _after_fork():
+            # process is spawned, nothing to do
+            pass
+
     class ForkServerProcess(process.BaseProcess):
         _start_method = 'forkserver'
         @staticmethod
@@ -326,6 +335,11 @@
             from .popen_spawn_win32 import Popen
             return Popen(process_obj)
 
+        @staticmethod
+        def _after_fork():
+            # process is spawned, nothing to do
+            pass
+
     class SpawnContext(BaseContext):
         _name = 'spawn'
         Process = SpawnProcess
diff --git a/common/py3-stdlib/multiprocessing/managers.py b/common/py3-stdlib/multiprocessing/managers.py
index b6b4cdd..22292c7 100644
--- a/common/py3-stdlib/multiprocessing/managers.py
+++ b/common/py3-stdlib/multiprocessing/managers.py
@@ -677,7 +677,7 @@
                 if hasattr(process, 'terminate'):
                     util.info('trying to `terminate()` manager process')
                     process.terminate()
-                    process.join(timeout=0.1)
+                    process.join(timeout=1.0)
                     if process.is_alive():
                         util.info('manager still alive after terminate')
 
diff --git a/common/py3-stdlib/multiprocessing/pool.py b/common/py3-stdlib/multiprocessing/pool.py
index bbe05a5..961d7e5 100644
--- a/common/py3-stdlib/multiprocessing/pool.py
+++ b/common/py3-stdlib/multiprocessing/pool.py
@@ -203,6 +203,9 @@
             processes = os.cpu_count() or 1
         if processes < 1:
             raise ValueError("Number of processes must be at least 1")
+        if maxtasksperchild is not None:
+            if not isinstance(maxtasksperchild, int) or maxtasksperchild <= 0:
+                raise ValueError("maxtasksperchild must be a positive int or None")
 
         if initializer is not None and not callable(initializer):
             raise TypeError('initializer must be a callable')
diff --git a/common/py3-stdlib/multiprocessing/process.py b/common/py3-stdlib/multiprocessing/process.py
index 0b2e0b4..2d5372e 100644
--- a/common/py3-stdlib/multiprocessing/process.py
+++ b/common/py3-stdlib/multiprocessing/process.py
@@ -304,8 +304,7 @@
             if threading._HAVE_THREAD_NATIVE_ID:
                 threading.main_thread()._set_native_id()
             try:
-                util._finalizer_registry.clear()
-                util._run_after_forkers()
+                self._after_fork()
             finally:
                 # delay finalization of the old process object until after
                 # _run_after_forkers() is executed
@@ -336,6 +335,13 @@
 
         return exitcode
 
+    @staticmethod
+    def _after_fork():
+        from . import util
+        util._finalizer_registry.clear()
+        util._run_after_forkers()
+
+
 #
 # We subclass bytes to avoid accidental transmission of auth keys over network
 #
diff --git a/common/py3-stdlib/multiprocessing/queues.py b/common/py3-stdlib/multiprocessing/queues.py
index a290181..f37f114 100644
--- a/common/py3-stdlib/multiprocessing/queues.py
+++ b/common/py3-stdlib/multiprocessing/queues.py
@@ -139,13 +139,10 @@
 
     def close(self):
         self._closed = True
-        try:
-            self._reader.close()
-        finally:
-            close = self._close
-            if close:
-                self._close = None
-                close()
+        close = self._close
+        if close:
+            self._close = None
+            close()
 
     def join_thread(self):
         debug('Queue.join_thread()')
@@ -169,8 +166,9 @@
         self._thread = threading.Thread(
             target=Queue._feed,
             args=(self._buffer, self._notempty, self._send_bytes,
-                  self._wlock, self._writer.close, self._ignore_epipe,
-                  self._on_queue_feeder_error, self._sem),
+                  self._wlock, self._reader.close, self._writer.close,
+                  self._ignore_epipe, self._on_queue_feeder_error,
+                  self._sem),
             name='QueueFeederThread'
         )
         self._thread.daemon = True
@@ -211,8 +209,8 @@
             notempty.notify()
 
     @staticmethod
-    def _feed(buffer, notempty, send_bytes, writelock, close, ignore_epipe,
-              onerror, queue_sem):
+    def _feed(buffer, notempty, send_bytes, writelock, reader_close,
+              writer_close, ignore_epipe, onerror, queue_sem):
         debug('starting thread to feed data to pipe')
         nacquire = notempty.acquire
         nrelease = notempty.release
@@ -238,7 +236,8 @@
                         obj = bpopleft()
                         if obj is sentinel:
                             debug('feeder thread got sentinel -- exiting')
-                            close()
+                            reader_close()
+                            writer_close()
                             return
 
                         # serialize the data before acquiring the lock
diff --git a/common/py3-stdlib/multiprocessing/resource_tracker.py b/common/py3-stdlib/multiprocessing/resource_tracker.py
index cc42dbd..ea36950 100644
--- a/common/py3-stdlib/multiprocessing/resource_tracker.py
+++ b/common/py3-stdlib/multiprocessing/resource_tracker.py
@@ -161,10 +161,10 @@
     def _send(self, cmd, name, rtype):
         self.ensure_running()
         msg = '{0}:{1}:{2}\n'.format(cmd, name, rtype).encode('ascii')
-        if len(name) > 512:
+        if len(msg) > 512:
             # posix guarantees that writes to a pipe of less than PIPE_BUF
             # bytes are atomic, and that PIPE_BUF >= 512
-            raise ValueError('name too long')
+            raise ValueError('msg too long')
         nbytes = os.write(self._fd, msg)
         assert nbytes == len(msg), "nbytes {0:n} but len(msg) {1:n}".format(
             nbytes, len(msg))
diff --git a/common/py3-stdlib/multiprocessing/shared_memory.py b/common/py3-stdlib/multiprocessing/shared_memory.py
index 122b3fc..9a1e5aa 100644
--- a/common/py3-stdlib/multiprocessing/shared_memory.py
+++ b/common/py3-stdlib/multiprocessing/shared_memory.py
@@ -23,6 +23,7 @@
     import _posixshmem
     _USE_POSIX = True
 
+from . import resource_tracker
 
 _O_CREX = os.O_CREAT | os.O_EXCL
 
@@ -116,8 +117,7 @@
                 self.unlink()
                 raise
 
-            from .resource_tracker import register
-            register(self._name, "shared_memory")
+            resource_tracker.register(self._name, "shared_memory")
 
         else:
 
@@ -173,7 +173,10 @@
                     )
                 finally:
                     _winapi.CloseHandle(h_map)
-                size = _winapi.VirtualQuerySize(p_buf)
+                try:
+                    size = _winapi.VirtualQuerySize(p_buf)
+                finally:
+                    _winapi.UnmapViewOfFile(p_buf)
                 self._mmap = mmap.mmap(-1, size, tagname=name)
 
         self._size = size
@@ -237,9 +240,8 @@
         called once (and only once) across all processes which have access
         to the shared memory block."""
         if _USE_POSIX and self._name:
-            from .resource_tracker import unregister
             _posixshmem.shm_unlink(self._name)
-            unregister(self._name, "shared_memory")
+            resource_tracker.unregister(self._name, "shared_memory")
 
 
 _encoding = "utf8"
diff --git a/common/py3-stdlib/multiprocessing/util.py b/common/py3-stdlib/multiprocessing/util.py
index a468333..9e07a4e 100644
--- a/common/py3-stdlib/multiprocessing/util.py
+++ b/common/py3-stdlib/multiprocessing/util.py
@@ -120,7 +120,7 @@
         return address[0] == 0
     elif isinstance(address, str):
         return address[0] == "\0"
-    raise TypeError('address type of {address!r} unrecognized')
+    raise TypeError(f'address type of {address!r} unrecognized')
 
 
 abstract_sockets_supported = _platform_supports_abstract_sockets()
diff --git a/common/py3-stdlib/ntpath.py b/common/py3-stdlib/ntpath.py
index 527c7ae..c14e5c7 100644
--- a/common/py3-stdlib/ntpath.py
+++ b/common/py3-stdlib/ntpath.py
@@ -23,6 +23,7 @@
 import genericpath
 from genericpath import *
 
+
 __all__ = ["normcase","isabs","join","splitdrive","split","splitext",
            "basename","dirname","commonprefix","getsize","getmtime",
            "getatime","getctime", "islink","exists","lexists","isdir","isfile",
@@ -41,14 +42,39 @@
 # Other normalizations (such as optimizing '../' away) are not done
 # (this is done by normpath).
 
-def normcase(s):
-    """Normalize case of pathname.
+try:
+    from _winapi import (
+        LCMapStringEx as _LCMapStringEx,
+        LOCALE_NAME_INVARIANT as _LOCALE_NAME_INVARIANT,
+        LCMAP_LOWERCASE as _LCMAP_LOWERCASE)
 
-    Makes all characters lowercase and all slashes into backslashes."""
-    s = os.fspath(s)
-    if isinstance(s, bytes):
-        return s.replace(b'/', b'\\').lower()
-    else:
+    def normcase(s):
+        """Normalize case of pathname.
+
+        Makes all characters lowercase and all slashes into backslashes.
+        """
+        s = os.fspath(s)
+        if not s:
+            return s
+        if isinstance(s, bytes):
+            encoding = sys.getfilesystemencoding()
+            s = s.decode(encoding, 'surrogateescape').replace('/', '\\')
+            s = _LCMapStringEx(_LOCALE_NAME_INVARIANT,
+                               _LCMAP_LOWERCASE, s)
+            return s.encode(encoding, 'surrogateescape')
+        else:
+            return _LCMapStringEx(_LOCALE_NAME_INVARIANT,
+                                  _LCMAP_LOWERCASE,
+                                  s.replace('/', '\\'))
+except ImportError:
+    def normcase(s):
+        """Normalize case of pathname.
+
+        Makes all characters lowercase and all slashes into backslashes.
+        """
+        s = os.fspath(s)
+        if isinstance(s, bytes):
+            return os.fsencode(os.fsdecode(s).replace('/', '\\').lower())
         return s.replace('/', '\\').lower()
 
 
@@ -599,12 +625,15 @@
         # 21: ERROR_NOT_READY (implies drive with no media)
         # 32: ERROR_SHARING_VIOLATION (probably an NTFS paging file)
         # 50: ERROR_NOT_SUPPORTED
+        # 53: ERROR_BAD_NETPATH
+        # 65: ERROR_NETWORK_ACCESS_DENIED
         # 67: ERROR_BAD_NET_NAME (implies remote server unavailable)
         # 87: ERROR_INVALID_PARAMETER
         # 123: ERROR_INVALID_NAME
+        # 161: ERROR_BAD_PATHNAME
         # 1920: ERROR_CANT_ACCESS_FILE
         # 1921: ERROR_CANT_RESOLVE_FILENAME (implies unfollowable symlink)
-        allowed_winerror = 1, 2, 3, 5, 21, 32, 50, 67, 87, 123, 1920, 1921
+        allowed_winerror = 1, 2, 3, 5, 21, 32, 50, 53, 65, 67, 87, 123, 161, 1920, 1921
 
         # Non-strict algorithm is to find as much of the target directory
         # as we can and join the rest.
diff --git a/common/py3-stdlib/numbers.py b/common/py3-stdlib/numbers.py
index 5b98e64..0985dd8 100644
--- a/common/py3-stdlib/numbers.py
+++ b/common/py3-stdlib/numbers.py
@@ -288,7 +288,7 @@
         so that ratios of huge integers convert without overflowing.
 
         """
-        return self.numerator / self.denominator
+        return int(self.numerator) / int(self.denominator)
 
 
 class Integral(Rational):
diff --git a/common/py3-stdlib/os.py b/common/py3-stdlib/os.py
index d26cfc9..4f2ffce 100644
--- a/common/py3-stdlib/os.py
+++ b/common/py3-stdlib/os.py
@@ -288,7 +288,8 @@
         dirpath, dirnames, filenames
 
     dirpath is a string, the path to the directory.  dirnames is a list of
-    the names of the subdirectories in dirpath (excluding '.' and '..').
+    the names of the subdirectories in dirpath (including symlinks to directories,
+    and excluding '.' and '..').
     filenames is a list of the names of the non-directory files in dirpath.
     Note that the names in the lists are just names, with no path components.
     To get a full path (which begins with top) to a file or directory in
diff --git a/common/py3-stdlib/pathlib.py b/common/py3-stdlib/pathlib.py
index 621fba0..97b23ca 100644
--- a/common/py3-stdlib/pathlib.py
+++ b/common/py3-stdlib/pathlib.py
@@ -528,6 +528,8 @@
 
         if idx >= len(self) or idx < -len(self):
             raise IndexError(idx)
+        if idx < 0:
+            idx += len(self)
         return self._pathcls._from_parsed_parts(self._drv, self._root,
                                                 self._parts[:-idx - 1])
 
diff --git a/common/py3-stdlib/pdb.py b/common/py3-stdlib/pdb.py
index 7ab50b4..3bdb2ac 100755
--- a/common/py3-stdlib/pdb.py
+++ b/common/py3-stdlib/pdb.py
@@ -104,15 +104,6 @@
                 return funcname, filename, lineno
     return None
 
-def getsourcelines(obj):
-    lines, lineno = inspect.findsource(obj)
-    if inspect.isframe(obj) and obj.f_globals is obj.f_locals:
-        # must be a module frame: do not try to cut a block out of it
-        return lines, 1
-    elif inspect.ismodule(obj):
-        return lines, 1
-    return inspect.getblock(lines[lineno:]), lineno+1
-
 def lasti2lineno(code, lasti):
     linestarts = list(dis.findlinestarts(code))
     linestarts.reverse()
@@ -1248,6 +1239,12 @@
         if last is None:
             last = first + 10
         filename = self.curframe.f_code.co_filename
+        # gh-93696: stdlib frozen modules provide a useful __file__
+        # this workaround can be removed with the closure of gh-89815
+        if filename.startswith("<frozen"):
+            tmp = self.curframe.f_globals.get("__file__")
+            if isinstance(tmp, str):
+                filename = tmp
         breaklist = self.get_file_breaks(filename)
         try:
             lines = linecache.getlines(filename, self.curframe.f_globals)
@@ -1267,7 +1264,7 @@
         filename = self.curframe.f_code.co_filename
         breaklist = self.get_file_breaks(filename)
         try:
-            lines, lineno = getsourcelines(self.curframe)
+            lines, lineno = inspect.getsourcelines(self.curframe)
         except OSError as err:
             self.error(err)
             return
@@ -1283,7 +1280,7 @@
         except:
             return
         try:
-            lines, lineno = getsourcelines(obj)
+            lines, lineno = inspect.getsourcelines(obj)
         except (OSError, TypeError) as err:
             self.error(err)
             return
diff --git a/common/py3-stdlib/pickle.py b/common/py3-stdlib/pickle.py
index e7f30f2..f027e04 100644
--- a/common/py3-stdlib/pickle.py
+++ b/common/py3-stdlib/pickle.py
@@ -619,7 +619,7 @@
                     "persistent IDs in protocol 0 must be ASCII strings")
 
     def save_reduce(self, func, args, state=None, listitems=None,
-                    dictitems=None, state_setter=None, obj=None):
+                    dictitems=None, state_setter=None, *, obj=None):
         # This API is called by some subclasses
 
         if not isinstance(args, tuple):
diff --git a/common/py3-stdlib/platform.py b/common/py3-stdlib/platform.py
index e32f9c1..6a820c9 100755
--- a/common/py3-stdlib/platform.py
+++ b/common/py3-stdlib/platform.py
@@ -776,6 +776,8 @@
     except when needed.
     """
 
+    _fields = ('system', 'node', 'release', 'version', 'machine', 'processor')
+
     @functools.cached_property
     def processor(self):
         return _unknown_as_blank(_Processor.get())
@@ -789,7 +791,7 @@
     @classmethod
     def _make(cls, iterable):
         # override factory to affect length check
-        num_fields = len(cls._fields)
+        num_fields = len(cls._fields) - 1
         result = cls.__new__(cls, *iterable)
         if len(result) != num_fields + 1:
             msg = f'Expected {num_fields} arguments, got {len(result)}'
@@ -803,7 +805,7 @@
         return len(tuple(iter(self)))
 
     def __reduce__(self):
-        return uname_result, tuple(self)[:len(self._fields)]
+        return uname_result, tuple(self)[:len(self._fields) - 1]
 
 
 _uname_cache = None
diff --git a/common/py3-stdlib/plistlib.py b/common/py3-stdlib/plistlib.py
index 2eeebe4..d6c997e 100644
--- a/common/py3-stdlib/plistlib.py
+++ b/common/py3-stdlib/plistlib.py
@@ -21,6 +21,9 @@
 
 Generate Plist example:
 
+    import datetime
+    import plistlib
+
     pl = dict(
         aString = "Doodah",
         aList = ["A", "B", 12, 32.1, [1, 2, 3]],
@@ -28,22 +31,28 @@
         anInt = 728,
         aDict = dict(
             anotherString = "<hello & hi there!>",
-            aUnicodeValue = "M\xe4ssig, Ma\xdf",
+            aThirdString = "M\xe4ssig, Ma\xdf",
             aTrueValue = True,
             aFalseValue = False,
         ),
         someData = b"<binary gunk>",
         someMoreData = b"<lots of binary gunk>" * 10,
-        aDate = datetime.datetime.fromtimestamp(time.mktime(time.gmtime())),
+        aDate = datetime.datetime.now()
     )
-    with open(fileName, 'wb') as fp:
-        dump(pl, fp)
+    print(plistlib.dumps(pl).decode())
 
 Parse Plist example:
 
-    with open(fileName, 'rb') as fp:
-        pl = load(fp)
-    print(pl["aKey"])
+    import plistlib
+
+    plist = b'''<plist version="1.0">
+    <dict>
+        <key>foo</key>
+        <string>bar</string>
+    </dict>
+    </plist>'''
+    pl = plistlib.loads(plist)
+    print(pl["foo"])
 """
 __all__ = [
     "InvalidFileException", "FMT_XML", "FMT_BINARY", "load", "dump", "loads", "dumps", "UID"
@@ -152,7 +161,7 @@
 def _escape(text):
     m = _controlCharPat.search(text)
     if m is not None:
-        raise ValueError("strings can't contains control characters; "
+        raise ValueError("strings can't contain control characters; "
                          "use bytes instead")
     text = text.replace("\r\n", "\n")       # convert DOS line endings
     text = text.replace("\r", "\n")         # convert Mac line endings
diff --git a/common/py3-stdlib/posixpath.py b/common/py3-stdlib/posixpath.py
index 1953746..e550b47 100644
--- a/common/py3-stdlib/posixpath.py
+++ b/common/py3-stdlib/posixpath.py
@@ -195,6 +195,7 @@
         if stat.S_ISLNK(s1.st_mode):
             return False
 
+    path = os.fspath(path)
     if isinstance(path, bytes):
         parent = join(path, b'..')
     else:
@@ -352,7 +353,7 @@
     initial_slashes = path.startswith(sep)
     # POSIX allows one or two initial slashes, but treats three or more
     # as single slash.
-    # (see http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13)
+    # (see https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13)
     if (initial_slashes and
         path.startswith(sep*2) and not path.startswith(sep*3)):
         initial_slashes = 2
diff --git a/common/py3-stdlib/pstats.py b/common/py3-stdlib/pstats.py
index 0f93ae0..ac88c04 100644
--- a/common/py3-stdlib/pstats.py
+++ b/common/py3-stdlib/pstats.py
@@ -56,7 +56,7 @@
 
 @dataclass(unsafe_hash=True)
 class FunctionProfile:
-    ncalls: int
+    ncalls: str
     tottime: float
     percall_tottime: float
     cumtime: float
diff --git a/common/py3-stdlib/pydoc.py b/common/py3-stdlib/pydoc.py
index 4a8c10a..e00ba41 100755
--- a/common/py3-stdlib/pydoc.py
+++ b/common/py3-stdlib/pydoc.py
@@ -69,6 +69,7 @@
 import sysconfig
 import time
 import tokenize
+import types
 import urllib.parse
 import warnings
 from collections import deque
@@ -90,13 +91,16 @@
             normdirs.append(normdir)
     return dirs
 
+def _isclass(object):
+    return inspect.isclass(object) and not isinstance(object, types.GenericAlias)
+
 def _findclass(func):
     cls = sys.modules.get(func.__module__)
     if cls is None:
         return None
     for name in func.__qualname__.split('.')[:-1]:
         cls = getattr(cls, name)
-    if not inspect.isclass(cls):
+    if not _isclass(cls):
         return None
     return cls
 
@@ -104,7 +108,7 @@
     if inspect.ismethod(obj):
         name = obj.__func__.__name__
         self = obj.__self__
-        if (inspect.isclass(self) and
+        if (_isclass(self) and
             getattr(getattr(self, name, None), '__func__') is obj.__func__):
             # classmethod
             cls = self
@@ -118,7 +122,7 @@
     elif inspect.isbuiltin(obj):
         name = obj.__name__
         self = obj.__self__
-        if (inspect.isclass(self) and
+        if (_isclass(self) and
             self.__qualname__ + '.' + name == obj.__qualname__):
             # classmethod
             cls = self
@@ -205,7 +209,7 @@
 
 def isdata(object):
     """Check if an object is of a type that probably means it's data."""
-    return not (inspect.ismodule(object) or inspect.isclass(object) or
+    return not (inspect.ismodule(object) or _isclass(object) or
                 inspect.isroutine(object) or inspect.isframe(object) or
                 inspect.istraceback(object) or inspect.iscode(object))
 
@@ -470,7 +474,7 @@
         # by lacking a __name__ attribute) and an instance.
         try:
             if inspect.ismodule(object): return self.docmodule(*args)
-            if inspect.isclass(object): return self.docclass(*args)
+            if _isclass(object): return self.docclass(*args)
             if inspect.isroutine(object): return self.docroutine(*args)
         except AttributeError:
             pass
@@ -775,7 +779,7 @@
         modules = inspect.getmembers(object, inspect.ismodule)
 
         classes, cdict = [], {}
-        for key, value in inspect.getmembers(object, inspect.isclass):
+        for key, value in inspect.getmembers(object, _isclass):
             # if __all__ exists, believe it.  Otherwise use old heuristic.
             if (all is not None or
                 (inspect.getmodule(value) or object) is object):
@@ -1217,7 +1221,7 @@
             result = result + self.section('DESCRIPTION', desc)
 
         classes = []
-        for key, value in inspect.getmembers(object, inspect.isclass):
+        for key, value in inspect.getmembers(object, _isclass):
             # if __all__ exists, believe it.  Otherwise use old heuristic.
             if (all is not None
                 or (inspect.getmodule(value) or object) is object):
@@ -1699,7 +1703,7 @@
         return 'member descriptor %s.%s.%s' % (
             thing.__objclass__.__module__, thing.__objclass__.__name__,
             thing.__name__)
-    if inspect.isclass(thing):
+    if _isclass(thing):
         return 'class ' + thing.__name__
     if inspect.isfunction(thing):
         return 'function ' + thing.__name__
@@ -1760,7 +1764,7 @@
         desc += ' in module ' + module.__name__
 
     if not (inspect.ismodule(object) or
-              inspect.isclass(object) or
+              _isclass(object) or
               inspect.isroutine(object) or
               inspect.isdatadescriptor(object) or
               _getdoc(object)):
diff --git a/common/py3-stdlib/pydoc_data/topics.py b/common/py3-stdlib/pydoc_data/topics.py
index ac7d16c..1637f38 100644
--- a/common/py3-stdlib/pydoc_data/topics.py
+++ b/common/py3-stdlib/pydoc_data/topics.py
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Autogenerated by Sphinx on Wed Mar 16 11:26:55 2022
+# Autogenerated by Sphinx on Tue Apr  4 22:56:51 2023
 topics = {'assert': 'The "assert" statement\n'
            '**********************\n'
            '\n'
@@ -93,11 +93,7 @@
                '  optionally in parentheses, the object is assigned to that '
                'target.\n'
                '\n'
-               '* Else: The object must be an iterable with the same number of '
-               'items\n'
-               '  as there are targets in the target list, and the items are '
-               'assigned,\n'
-               '  from left to right, to the corresponding targets.\n'
+               '* Else:\n'
                '\n'
                '  * If the target list contains one target prefixed with an '
                'asterisk,\n'
@@ -362,7 +358,7 @@
                'yield_expression)]\n'
                '\n'
                'The difference from normal Assignment statements is that only '
-               'single\n'
+               'a single\n'
                'target is allowed.\n'
                '\n'
                'For simple names as assignment targets, if in class or module '
@@ -412,12 +408,13 @@
                'analysis\n'
                '     tools and IDEs.\n'
                '\n'
-               'Changed in version 3.8: Now annotated assignments allow same\n'
-               'expressions in the right hand side as the regular '
-               'assignments.\n'
-               'Previously, some expressions (like un-parenthesized tuple '
-               'expressions)\n'
-               'caused a syntax error.\n',
+               'Changed in version 3.8: Now annotated assignments allow the '
+               'same\n'
+               'expressions in the right hand side as regular assignments. '
+               'Previously,\n'
+               'some expressions (like un-parenthesized tuple expressions) '
+               'caused a\n'
+               'syntax error.\n',
  'async': 'Coroutines\n'
           '**********\n'
           '\n'
@@ -1139,10 +1136,11 @@
                      'future, a\n'
                      '  check may be added to prevent this.\n'
                      '\n'
-                     '* Nonempty *__slots__* does not work for classes derived '
-                     'from\n'
-                     '  “variable-length” built-in types such as "int", '
-                     '"bytes" and "tuple".\n'
+                     '* "TypeError" will be raised if nonempty *__slots__* are '
+                     'defined for a\n'
+                     '  class derived from a ""variable-length" built-in type" '
+                     'such as\n'
+                     '  "int", "bytes", and "tuple".\n'
                      '\n'
                      '* Any non-string *iterable* may be assigned to '
                      '*__slots__*.\n'
@@ -1678,10 +1676,26 @@
           'If the syntax "**expression" appears in the function call,\n'
           '"expression" must evaluate to a *mapping*, the contents of which '
           'are\n'
-          'treated as additional keyword arguments.  If a keyword is already\n'
-          'present (as an explicit keyword argument, or from another '
-          'unpacking),\n'
-          'a "TypeError" exception is raised.\n'
+          'treated as additional keyword arguments. If a parameter matching a '
+          'key\n'
+          'has already been given a value (by an explicit keyword argument, '
+          'or\n'
+          'from another unpacking), a "TypeError" exception is raised.\n'
+          '\n'
+          'When "**expression" is used, each key in this mapping must be a\n'
+          'string. Each value from the mapping is assigned to the first '
+          'formal\n'
+          'parameter eligible for keyword assignment whose name is equal to '
+          'the\n'
+          'key. A key need not be a Python identifier (e.g. ""max-temp °F"" '
+          'is\n'
+          'acceptable, although it will not match any formal parameter that '
+          'could\n'
+          'be declared). If there is no match to a formal parameter the '
+          'key-value\n'
+          'pair is collected by the "**" parameter, if there is one, or if '
+          'there\n'
+          'is not, a "TypeError" exception is raised.\n'
           '\n'
           'Formal parameters using the syntax "*identifier" or "**identifier"\n'
           'cannot be used as positional argument slots or as keyword argument\n'
@@ -2029,7 +2043,7 @@
                 '\n'
                 '* Mappings (instances of "dict") compare equal if and only if '
                 'they\n'
-                '  have equal *(key, value)* pairs. Equality comparison of the '
+                '  have equal "(key, value)" pairs. Equality comparison of the '
                 'keys and\n'
                 '  values enforces reflexivity.\n'
                 '\n'
@@ -2378,12 +2392,10 @@
              'finished,\n'
              'but if the sequence is empty, they will not have been assigned '
              'to at\n'
-             'all by the loop.  Hint: the built-in function "range()" returns '
-             'an\n'
-             'iterator of integers suitable to emulate the effect of Pascal’s '
-             '"for i\n'
-             ':= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, '
-             '2]".\n'
+             'all by the loop.  Hint: the built-in type "range()" represents\n'
+             'immutable arithmetic sequences of integers. For instance, '
+             'iterating\n'
+             '"range(3)" successively yields 0, 1, and then 2.\n'
              '\n'
              '\n'
              'The "try" statement\n'
@@ -2418,11 +2430,11 @@
              'resulting\n'
              'object is “compatible” with the exception.  An object is '
              'compatible\n'
-             'with an exception if it is the class or a base class of the '
-             'exception\n'
-             'object, or a tuple containing an item that is the class or a '
+             'with an exception if the object is the class or a *non-virtual '
              'base\n'
-             'class of the exception object.\n'
+             'class* of the exception object, or a tuple containing an item '
+             'that is\n'
+             'the class or a non-virtual base class of the exception object.\n'
              '\n'
              'If no except clause matches the exception, the search for an '
              'exception\n'
@@ -2631,7 +2643,7 @@
              'the\n'
              '     target list, it will be treated the same as an error '
              'occurring\n'
-             '     within the suite would be. See step 6 below.\n'
+             '     within the suite would be. See step 7 below.\n'
              '\n'
              '6. The suite is executed.\n'
              '\n'
@@ -2988,7 +3000,7 @@
              'AS\n'
              'pattern binds the subject to the name on the right of the as '
              'keyword\n'
-             'and succeeds. "capture_pattern" cannot be a a "_".\n'
+             'and succeeds. "capture_pattern" cannot be a "_".\n'
              '\n'
              'In simple terms "P as NAME" will match with "P", and on success '
              'it\n'
@@ -3433,8 +3445,8 @@
              '   there is matched against the whole object rather than an '
              'attribute.\n'
              '   For example "int(0|1)" matches the value "0", but not the '
-             'values\n'
-             '   "0.0" or "False".\n'
+             'value\n'
+             '   "0.0".\n'
              '\n'
              'In simple terms "CLS(P1, attr=P2)" matches only if the '
              'following\n'
@@ -4095,7 +4107,7 @@
                   '   invoking the superclass’s "__new__()" method using\n'
                   '   "super().__new__(cls[, ...])" with appropriate arguments '
                   'and then\n'
-                  '   modifying the newly-created instance as necessary before '
+                  '   modifying the newly created instance as necessary before '
                   'returning\n'
                   '   it.\n'
                   '\n'
@@ -4399,15 +4411,17 @@
                   'on members\n'
                   '   of hashed collections including "set", "frozenset", and '
                   '"dict".\n'
-                  '   "__hash__()" should return an integer. The only required '
-                  'property\n'
-                  '   is that objects which compare equal have the same hash '
-                  'value; it is\n'
-                  '   advised to mix together the hash values of the '
-                  'components of the\n'
-                  '   object that also play a part in comparison of objects by '
-                  'packing\n'
-                  '   them into a tuple and hashing the tuple. Example:\n'
+                  '   The "__hash__()" method should return an integer. The '
+                  'only required\n'
+                  '   property is that objects which compare equal have the '
+                  'same hash\n'
+                  '   value; it is advised to mix together the hash values of '
+                  'the\n'
+                  '   components of the object that also play a part in '
+                  'comparison of\n'
+                  '   objects by packing them into a tuple and hashing the '
+                  'tuple.\n'
+                  '   Example:\n'
                   '\n'
                   '      def __hash__(self):\n'
                   '          return hash((self.name, self.nick, self.color))\n'
@@ -4438,7 +4452,7 @@
                   'objects and\n'
                   '   implements an "__eq__()" method, it should not '
                   'implement\n'
-                  '   "__hash__()", since the implementation of hashable '
+                  '   "__hash__()", since the implementation of *hashable* '
                   'collections\n'
                   '   requires that a key’s hash value is immutable (if the '
                   'object’s hash\n'
@@ -4496,7 +4510,7 @@
                   'Python.This is\n'
                   '     intended to provide protection against a '
                   'denial-of-service caused\n'
-                  '     by carefully-chosen inputs that exploit the worst '
+                  '     by carefully chosen inputs that exploit the worst '
                   'case\n'
                   '     performance of a dict insertion, O(n^2) complexity.  '
                   'See\n'
@@ -4552,6 +4566,18 @@
              'the source.  The extension interface uses the modules "bdb" and '
              '"cmd".\n'
              '\n'
+             'See also:\n'
+             '\n'
+             '  Module "faulthandler"\n'
+             '     Used to dump Python tracebacks explicitly, on a fault, '
+             'after a\n'
+             '     timeout, or on a user signal.\n'
+             '\n'
+             '  Module "traceback"\n'
+             '     Standard interface to extract, format and print stack '
+             'traces of\n'
+             '     Python programs.\n'
+             '\n'
              'The debugger’s prompt is "(Pdb)". Typical usage to run a program '
              'under\n'
              'control of the debugger is:\n'
@@ -4577,7 +4603,7 @@
              'scripts.  For\n'
              'example:\n'
              '\n'
-             '   python3 -m pdb myscript.py\n'
+             '   python -m pdb myscript.py\n'
              '\n'
              'When invoked as a script, pdb will automatically enter '
              'post-mortem\n'
@@ -4597,7 +4623,7 @@
              '\n'
              'New in version 3.7: "pdb.py" now accepts a "-m" option that '
              'execute\n'
-             'modules similar to the way "python3 -m" does. As with a script, '
+             'modules similar to the way "python -m" does. As with a script, '
              'the\n'
              'debugger will pause execution just before the first line of the\n'
              'module.\n'
@@ -4661,8 +4687,8 @@
              'object)\n'
              '   under debugger control.  When "runeval()" returns, it returns '
              'the\n'
-             '   value of the expression.  Otherwise this function is similar '
-             'to\n'
+             '   value of the *expression*.  Otherwise this function is '
+             'similar to\n'
              '   "run()".\n'
              '\n'
              'pdb.runcall(function, *args, **kwds)\n'
@@ -4810,7 +4836,10 @@
              'is\n'
              'applied to separating the commands; the input is split at the '
              'first\n'
-             '";;" pair, even if it is in the middle of a quoted string.\n'
+             '";;" pair, even if it is in the middle of a quoted string. A\n'
+             'workaround for strings with double semicolons is to use '
+             'implicit\n'
+             'string concatenation "\';\'\';\'" or "";"";"".\n'
              '\n'
              'If a file ".pdbrc" exists in the user’s home directory or in '
              'the\n'
@@ -4916,14 +4945,15 @@
              'ignore bpnumber [count]\n'
              '\n'
              '   Set the ignore count for the given breakpoint number.  If '
-             'count is\n'
-             '   omitted, the ignore count is set to 0.  A breakpoint becomes '
-             'active\n'
-             '   when the ignore count is zero.  When non-zero, the count is\n'
-             '   decremented each time the breakpoint is reached and the '
-             'breakpoint\n'
-             '   is not disabled and any associated condition evaluates to '
-             'true.\n'
+             '*count*\n'
+             '   is omitted, the ignore count is set to 0.  A breakpoint '
+             'becomes\n'
+             '   active when the ignore count is zero.  When non-zero, the '
+             '*count*\n'
+             '   is decremented each time the breakpoint is reached and the\n'
+             '   breakpoint is not disabled and any associated condition '
+             'evaluates\n'
+             '   to true.\n'
              '\n'
              'condition bpnumber [condition]\n'
              '\n'
@@ -4973,7 +5003,7 @@
              '   breakpoint—which could have its own command list, leading to\n'
              '   ambiguities about which list to execute.\n'
              '\n'
-             '   If you use the ‘silent’ command in the command list, the '
+             '   If you use the "silent" command in the command list, the '
              'usual\n'
              '   message about stopping at a breakpoint is not printed.  This '
              'may be\n'
@@ -5008,11 +5038,10 @@
              'number\n'
              '   greater than the current one is reached.\n'
              '\n'
-             '   With a line number, continue execution until a line with a '
-             'number\n'
-             '   greater or equal to that is reached.  In both cases, also '
-             'stop when\n'
-             '   the current frame returns.\n'
+             '   With *lineno*, continue execution until a line with a number\n'
+             '   greater or equal to *lineno* is reached.  In both cases, also '
+             'stop\n'
+             '   when the current frame returns.\n'
              '\n'
              '   Changed in version 3.2: Allow giving an explicit line '
              'number.\n'
@@ -5076,9 +5105,8 @@
              '\n'
              'p expression\n'
              '\n'
-             '   Evaluate the *expression* in the current context and print '
-             'its\n'
-             '   value.\n'
+             '   Evaluate *expression* in the current context and print its '
+             'value.\n'
              '\n'
              '   Note:\n'
              '\n'
@@ -5088,26 +5116,26 @@
              '\n'
              'pp expression\n'
              '\n'
-             '   Like the "p" command, except the value of the expression is '
+             '   Like the "p" command, except the value of *expression* is '
              'pretty-\n'
              '   printed using the "pprint" module.\n'
              '\n'
              'whatis expression\n'
              '\n'
-             '   Print the type of the *expression*.\n'
+             '   Print the type of *expression*.\n'
              '\n'
              'source expression\n'
              '\n'
-             '   Try to get source code for the given object and display it.\n'
+             '   Try to get source code of *expression* and display it.\n'
              '\n'
              '   New in version 3.2.\n'
              '\n'
              'display [expression]\n'
              '\n'
-             '   Display the value of the expression if it changed, each time\n'
+             '   Display the value of *expression* if it changed, each time\n'
              '   execution stops in the current frame.\n'
              '\n'
-             '   Without expression, list all display expressions for the '
+             '   Without *expression*, list all display expressions for the '
              'current\n'
              '   frame.\n'
              '\n'
@@ -5115,10 +5143,10 @@
              '\n'
              'undisplay [expression]\n'
              '\n'
-             '   Do not display the expression any more in the current frame.\n'
-             '   Without expression, clear all display expressions for the '
-             'current\n'
-             '   frame.\n'
+             '   Do not display *expression* anymore in the current frame.  '
+             'Without\n'
+             '   *expression*, clear all display expressions for the current '
+             'frame.\n'
              '\n'
              '   New in version 3.2.\n'
              '\n'
@@ -5134,16 +5162,16 @@
              '\n'
              'alias [name [command]]\n'
              '\n'
-             '   Create an alias called *name* that executes *command*.  The '
-             'command\n'
-             '   must *not* be enclosed in quotes.  Replaceable parameters can '
-             'be\n'
-             '   indicated by "%1", "%2", and so on, while "%*" is replaced by '
-             'all\n'
-             '   the parameters. If no command is given, the current alias '
-             'for\n'
-             '   *name* is shown. If no arguments are given, all aliases are '
-             'listed.\n'
+             '   Create an alias called *name* that executes *command*.  The\n'
+             '   *command* must *not* be enclosed in quotes.  Replaceable '
+             'parameters\n'
+             '   can be indicated by "%1", "%2", and so on, while "%*" is '
+             'replaced\n'
+             '   by all the parameters. If *command* is omitted, the current '
+             'alias\n'
+             '   for *name* is shown. If no arguments are given, all aliases '
+             'are\n'
+             '   listed.\n'
              '\n'
              '   Aliases may be nested and can contain anything that can be '
              'legally\n'
@@ -5162,14 +5190,14 @@
              '   in the ".pdbrc" file):\n'
              '\n'
              '      # Print instance variables (usage "pi classInst")\n'
-             '      alias pi for k in %1.__dict__.keys(): '
-             'print("%1.",k,"=",%1.__dict__[k])\n'
+             '      alias pi for k in %1.__dict__.keys(): print(f"%1.{k} = '
+             '{%1.__dict__[k]}")\n'
              '      # Print instance variables in self\n'
              '      alias ps pi self\n'
              '\n'
              'unalias name\n'
              '\n'
-             '   Delete the specified alias.\n'
+             '   Delete the specified alias *name*.\n'
              '\n'
              '! statement\n'
              '\n'
@@ -5189,12 +5217,13 @@
              'run [args ...]\n'
              'restart [args ...]\n'
              '\n'
-             '   Restart the debugged Python program.  If an argument is '
-             'supplied,\n'
-             '   it is split with "shlex" and the result is used as the new\n'
-             '   "sys.argv". History, breakpoints, actions and debugger '
-             'options are\n'
-             '   preserved. "restart" is an alias for "run".\n'
+             '   Restart the debugged Python program.  If *args* is supplied, '
+             'it is\n'
+             '   split with "shlex" and the result is used as the new '
+             '"sys.argv".\n'
+             '   History, breakpoints, actions and debugger options are '
+             'preserved.\n'
+             '   "restart" is an alias for "run".\n'
              '\n'
              'q(uit)\n'
              '\n'
@@ -5203,11 +5232,11 @@
              '\n'
              'debug code\n'
              '\n'
-             '   Enter a recursive debugger that steps through the code '
-             'argument\n'
-             '   (which is an arbitrary expression or statement to be executed '
-             'in\n'
-             '   the current environment).\n'
+             '   Enter a recursive debugger that steps through *code* (which '
+             'is an\n'
+             '   arbitrary expression or statement to be executed in the '
+             'current\n'
+             '   environment).\n'
              '\n'
              'retval\n'
              '\n'
@@ -5391,11 +5420,11 @@
                'clause is\n'
                'selected depending on the class of the instance: it must '
                'reference the\n'
-               'class of the instance or a base class thereof.  The instance '
-               'can be\n'
-               'received by the handler and can carry additional information '
-               'about the\n'
-               'exceptional condition.\n'
+               'class of the instance or a *non-virtual base class* thereof. '
+               'The\n'
+               'instance can be received by the handler and can carry '
+               'additional\n'
+               'information about the exceptional condition.\n'
                '\n'
                'Note:\n'
                '\n'
@@ -5562,7 +5591,8 @@
               'be\n'
               'determined by scanning the entire text of the block for name '
               'binding\n'
-              'operations.\n'
+              'operations. See the FAQ entry on UnboundLocalError for '
+              'examples.\n'
               '\n'
               'If the "global" statement occurs within a block, all uses of '
               'the names\n'
@@ -5730,11 +5760,11 @@
               'clause is\n'
               'selected depending on the class of the instance: it must '
               'reference the\n'
-              'class of the instance or a base class thereof.  The instance '
-              'can be\n'
-              'received by the handler and can carry additional information '
-              'about the\n'
-              'exceptional condition.\n'
+              'class of the instance or a *non-virtual base class* thereof. '
+              'The\n'
+              'instance can be received by the handler and can carry '
+              'additional\n'
+              'information about the exceptional condition.\n'
               '\n'
               'Note:\n'
               '\n'
@@ -5870,10 +5900,9 @@
         '\n'
         'Names in the target list are not deleted when the loop is finished,\n'
         'but if the sequence is empty, they will not have been assigned to at\n'
-        'all by the loop.  Hint: the built-in function "range()" returns an\n'
-        'iterator of integers suitable to emulate the effect of Pascal’s "for '
-        'i\n'
-        ':= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, 2]".\n',
+        'all by the loop.  Hint: the built-in type "range()" represents\n'
+        'immutable arithmetic sequences of integers. For instance, iterating\n'
+        '"range(3)" successively yields 0, 1, and then 2.\n',
  'formatstrings': 'Format String Syntax\n'
                   '********************\n'
                   '\n'
@@ -7208,7 +7237,7 @@
            'the clauses had been separated out into individual import '
            'statements.\n'
            '\n'
-           'The details of the first step, finding and loading modules are\n'
+           'The details of the first step, finding and loading modules, are\n'
            'described in greater detail in the section on the import system, '
            'which\n'
            'also describes the various types of packages and modules that can '
@@ -7267,12 +7296,12 @@
            'Examples:\n'
            '\n'
            '   import foo                 # foo imported and bound locally\n'
-           '   import foo.bar.baz         # foo.bar.baz imported, foo bound '
-           'locally\n'
-           '   import foo.bar.baz as fbb  # foo.bar.baz imported and bound as '
-           'fbb\n'
-           '   from foo.bar import baz    # foo.bar.baz imported and bound as '
-           'baz\n'
+           '   import foo.bar.baz         # foo, foo.bar, and foo.bar.baz '
+           'imported, foo bound locally\n'
+           '   import foo.bar.baz as fbb  # foo, foo.bar, and foo.bar.baz '
+           'imported, foo.bar.baz bound as fbb\n'
+           '   from foo.bar import baz    # foo, foo.bar, and foo.bar.baz '
+           'imported, foo.bar.baz bound as baz\n'
            '   from foo import attr       # foo imported and foo.attr bound as '
            'attr\n'
            '\n'
@@ -7669,7 +7698,7 @@
            'within a code block.  The local variables of a code block can be\n'
            'determined by scanning the entire text of the block for name '
            'binding\n'
-           'operations.\n'
+           'operations. See the FAQ entry on UnboundLocalError for examples.\n'
            '\n'
            'If the "global" statement occurs within a block, all uses of the '
            'names\n'
@@ -8187,7 +8216,7 @@
                      '| "x(arguments...)", "x.attribute"                | '
                      'attribute reference                   |\n'
                      '+-------------------------------------------------+---------------------------------------+\n'
-                     '| "await" "x"                                     | '
+                     '| "await x"                                       | '
                      'Await expression                      |\n'
                      '+-------------------------------------------------+---------------------------------------+\n'
                      '| "**"                                            | '
@@ -8223,7 +8252,7 @@
                      '| ">=", "!=", "=="                                | '
                      'tests and identity tests              |\n'
                      '+-------------------------------------------------+---------------------------------------+\n'
-                     '| "not" "x"                                       | '
+                     '| "not x"                                         | '
                      'Boolean NOT                           |\n'
                      '+-------------------------------------------------+---------------------------------------+\n'
                      '| "and"                                           | '
@@ -8906,31 +8935,7 @@
                  '   still alive.  The list is in definition order.  Example:\n'
                  '\n'
                  '      >>> int.__subclasses__()\n'
-                 "      [<class 'bool'>]\n"
-                 '\n'
-                 '-[ Footnotes ]-\n'
-                 '\n'
-                 '[1] Additional information on these special methods may be '
-                 'found in\n'
-                 '    the Python Reference Manual (Basic customization).\n'
-                 '\n'
-                 '[2] As a consequence, the list "[1, 2]" is considered equal '
-                 'to "[1.0,\n'
-                 '    2.0]", and similarly for tuples.\n'
-                 '\n'
-                 '[3] They must have since the parser can’t tell the type of '
-                 'the\n'
-                 '    operands.\n'
-                 '\n'
-                 '[4] Cased characters are those with general category '
-                 'property being\n'
-                 '    one of “Lu” (Letter, uppercase), “Ll” (Letter, '
-                 'lowercase), or “Lt”\n'
-                 '    (Letter, titlecase).\n'
-                 '\n'
-                 '[5] To format only a tuple you should therefore provide a '
-                 'singleton\n'
-                 '    tuple whose only element is the tuple to be formatted.\n',
+                 "      [<class 'bool'>]\n",
  'specialnames': 'Special method names\n'
                  '********************\n'
                  '\n'
@@ -8999,7 +9004,7 @@
                  '   invoking the superclass’s "__new__()" method using\n'
                  '   "super().__new__(cls[, ...])" with appropriate arguments '
                  'and then\n'
-                 '   modifying the newly-created instance as necessary before '
+                 '   modifying the newly created instance as necessary before '
                  'returning\n'
                  '   it.\n'
                  '\n'
@@ -9303,15 +9308,17 @@
                  'on members\n'
                  '   of hashed collections including "set", "frozenset", and '
                  '"dict".\n'
-                 '   "__hash__()" should return an integer. The only required '
-                 'property\n'
-                 '   is that objects which compare equal have the same hash '
-                 'value; it is\n'
-                 '   advised to mix together the hash values of the components '
-                 'of the\n'
-                 '   object that also play a part in comparison of objects by '
-                 'packing\n'
-                 '   them into a tuple and hashing the tuple. Example:\n'
+                 '   The "__hash__()" method should return an integer. The '
+                 'only required\n'
+                 '   property is that objects which compare equal have the '
+                 'same hash\n'
+                 '   value; it is advised to mix together the hash values of '
+                 'the\n'
+                 '   components of the object that also play a part in '
+                 'comparison of\n'
+                 '   objects by packing them into a tuple and hashing the '
+                 'tuple.\n'
+                 '   Example:\n'
                  '\n'
                  '      def __hash__(self):\n'
                  '          return hash((self.name, self.nick, self.color))\n'
@@ -9341,7 +9348,7 @@
                  '   hashable collections.  If a class defines mutable objects '
                  'and\n'
                  '   implements an "__eq__()" method, it should not implement\n'
-                 '   "__hash__()", since the implementation of hashable '
+                 '   "__hash__()", since the implementation of *hashable* '
                  'collections\n'
                  '   requires that a key’s hash value is immutable (if the '
                  'object’s hash\n'
@@ -9398,7 +9405,7 @@
                  'is\n'
                  '     intended to provide protection against a '
                  'denial-of-service caused\n'
-                 '     by carefully-chosen inputs that exploit the worst case\n'
+                 '     by carefully chosen inputs that exploit the worst case\n'
                  '     performance of a dict insertion, O(n^2) complexity.  '
                  'See\n'
                  '     http://www.ocert.org/advisories/ocert-2011-003.html '
@@ -9879,10 +9886,11 @@
                  'future, a\n'
                  '  check may be added to prevent this.\n'
                  '\n'
-                 '* Nonempty *__slots__* does not work for classes derived '
-                 'from\n'
-                 '  “variable-length” built-in types such as "int", "bytes" '
-                 'and "tuple".\n'
+                 '* "TypeError" will be raised if nonempty *__slots__* are '
+                 'defined for a\n'
+                 '  class derived from a ""variable-length" built-in type" '
+                 'such as\n'
+                 '  "int", "bytes", and "tuple".\n'
                  '\n'
                  '* Any non-string *iterable* may be assigned to *__slots__*.\n'
                  '\n'
@@ -11004,8 +11012,9 @@
                  'y)" is\n'
                  'typically invalid without special support in "MyClass". To '
                  'be able to\n'
-                 'use that kind of patterns, the class needs to define a\n'
-                 '*__match_args__* attribute.\n'
+                 'use that kind of pattern, the class needs to define a '
+                 '*__match_args__*\n'
+                 'attribute.\n'
                  '\n'
                  'object.__match_args__\n'
                  '\n'
@@ -11210,37 +11219,41 @@
                    '*start* and\n'
                    '   *end* are interpreted as in slice notation.\n'
                    '\n'
+                   '   If *sub* is empty, returns the number of empty strings '
+                   'between\n'
+                   '   characters which is the length of the string plus one.\n'
+                   '\n'
                    "str.encode(encoding='utf-8', errors='strict')\n"
                    '\n'
-                   '   Return an encoded version of the string as a bytes '
-                   'object. Default\n'
-                   '   encoding is "\'utf-8\'". *errors* may be given to set a '
-                   'different\n'
-                   '   error handling scheme. The default for *errors* is '
-                   '"\'strict\'",\n'
-                   '   meaning that encoding errors raise a "UnicodeError". '
+                   '   Return the string encoded to "bytes".\n'
+                   '\n'
+                   '   *encoding* defaults to "\'utf-8\'"; see Standard '
+                   'Encodings for\n'
+                   '   possible values.\n'
+                   '\n'
+                   '   *errors* controls how encoding errors are handled. If '
+                   '"\'strict\'"\n'
+                   '   (the default), a "UnicodeError" exception is raised. '
                    'Other possible\n'
                    '   values are "\'ignore\'", "\'replace\'", '
                    '"\'xmlcharrefreplace\'",\n'
                    '   "\'backslashreplace\'" and any other name registered '
                    'via\n'
-                   '   "codecs.register_error()", see section Error Handlers. '
-                   'For a list\n'
-                   '   of possible encodings, see section Standard Encodings.\n'
+                   '   "codecs.register_error()". See Error Handlers for '
+                   'details.\n'
                    '\n'
-                   '   By default, the *errors* argument is not checked for '
-                   'best\n'
-                   '   performances, but only used at the first encoding '
-                   'error. Enable the\n'
-                   '   Python Development Mode, or use a debug build to check '
-                   '*errors*.\n'
+                   '   For performance reasons, the value of *errors* is not '
+                   'checked for\n'
+                   '   validity unless an encoding error actually occurs, '
+                   'Python\n'
+                   '   Development Mode is enabled or a debug build is used.\n'
                    '\n'
-                   '   Changed in version 3.1: Support for keyword arguments '
-                   'added.\n'
+                   '   Changed in version 3.1: Added support for keyword '
+                   'arguments.\n'
                    '\n'
-                   '   Changed in version 3.9: The *errors* is now checked in '
-                   'development\n'
-                   '   mode and in debug mode.\n'
+                   '   Changed in version 3.9: The value of the *errors* '
+                   'argument is now\n'
+                   '   checked in Python Development Mode and in debug mode.\n'
                    '\n'
                    'str.endswith(suffix[, start[, end]])\n'
                    '\n'
@@ -11716,7 +11729,7 @@
                    'followed by\n'
                    '   the string itself.\n'
                    '\n'
-                   'str.rsplit(sep=None, maxsplit=- 1)\n'
+                   'str.rsplit(sep=None, maxsplit=-1)\n'
                    '\n'
                    '   Return a list of the words in the string, using *sep* '
                    'as the\n'
@@ -11757,7 +11770,7 @@
                    "      >>> 'Monty Python'.removesuffix(' Python')\n"
                    "      'Monty'\n"
                    '\n'
-                   'str.split(sep=None, maxsplit=- 1)\n'
+                   'str.split(sep=None, maxsplit=-1)\n'
                    '\n'
                    '   Return a list of the words in the string, using *sep* '
                    'as the\n'
@@ -11984,9 +11997,13 @@
                    '      >>> "they\'re bill\'s friends from the UK".title()\n'
                    '      "They\'Re Bill\'S Friends From The Uk"\n'
                    '\n'
-                   '   A workaround for apostrophes can be constructed using '
-                   'regular\n'
-                   '   expressions:\n'
+                   '   The "string.capwords()" function does not have this '
+                   'problem, as it\n'
+                   '   splits words on spaces only.\n'
+                   '\n'
+                   '   Alternatively, a workaround for apostrophes can be '
+                   'constructed\n'
+                   '   using regular expressions:\n'
                    '\n'
                    '      >>> import re\n'
                    '      >>> def titlecase(s):\n'
@@ -12108,12 +12125,15 @@
             'single quotes ("\'") or double quotes (""").  They can also be '
             'enclosed\n'
             'in matching groups of three single or double quotes (these are\n'
-            'generally referred to as *triple-quoted strings*).  The '
-            'backslash\n'
-            '("\\") character is used to escape characters that otherwise have '
-            'a\n'
-            'special meaning, such as newline, backslash itself, or the quote\n'
+            'generally referred to as *triple-quoted strings*). The backslash '
+            '("\\")\n'
+            'character is used to give special meaning to otherwise ordinary\n'
+            'characters like "n", which means ‘newline’ when escaped ("\\n"). '
+            'It can\n'
+            'also be used to escape characters that otherwise have a special\n'
+            'meaning, such as newline, backslash itself, or the quote '
             'character.\n'
+            'See escape sequences below for examples.\n'
             '\n'
             'Bytes literals are always prefixed with "\'b\'" or "\'B\'"; they '
             'produce\n'
@@ -12170,8 +12190,8 @@
             '| Escape Sequence   | Meaning                           | Notes   '
             '|\n'
             '|===================|===================================|=========|\n'
-            '| "\\newline"        | Backslash and newline ignored     '
-            '|         |\n'
+            '| "\\"<newline>      | Backslash and newline ignored     | '
+            '(1)     |\n'
             '+-------------------+-----------------------------------+---------+\n'
             '| "\\\\"              | Backslash ("\\")                   '
             '|         |\n'
@@ -12204,10 +12224,10 @@
             '|         |\n'
             '+-------------------+-----------------------------------+---------+\n'
             '| "\\ooo"            | Character with octal value *ooo*  | '
-            '(1,3)   |\n'
+            '(2,4)   |\n'
             '+-------------------+-----------------------------------+---------+\n'
             '| "\\xhh"            | Character with hex value *hh*     | '
-            '(2,3)   |\n'
+            '(3,4)   |\n'
             '+-------------------+-----------------------------------+---------+\n'
             '\n'
             'Escape sequences only recognized in string literals are:\n'
@@ -12217,39 +12237,51 @@
             '|\n'
             '|===================|===================================|=========|\n'
             '| "\\N{name}"        | Character named *name* in the     | '
-            '(4)     |\n'
+            '(5)     |\n'
             '|                   | Unicode database                  |         '
             '|\n'
             '+-------------------+-----------------------------------+---------+\n'
             '| "\\uxxxx"          | Character with 16-bit hex value   | '
-            '(5)     |\n'
+            '(6)     |\n'
             '|                   | *xxxx*                            |         '
             '|\n'
             '+-------------------+-----------------------------------+---------+\n'
             '| "\\Uxxxxxxxx"      | Character with 32-bit hex value   | '
-            '(6)     |\n'
+            '(7)     |\n'
             '|                   | *xxxxxxxx*                        |         '
             '|\n'
             '+-------------------+-----------------------------------+---------+\n'
             '\n'
             'Notes:\n'
             '\n'
-            '1. As in Standard C, up to three octal digits are accepted.\n'
+            '1. A backslash can be added at the end of a line to ignore the\n'
+            '   newline:\n'
             '\n'
-            '2. Unlike in Standard C, exactly two hex digits are required.\n'
+            "      >>> 'This string will not include \\\n"
+            "      ... backslashes or newline characters.'\n"
+            "      'This string will not include backslashes or newline "
+            "characters.'\n"
             '\n'
-            '3. In a bytes literal, hexadecimal and octal escapes denote the '
+            '   The same result can be achieved using triple-quoted strings, '
+            'or\n'
+            '   parentheses and string literal concatenation.\n'
+            '\n'
+            '2. As in Standard C, up to three octal digits are accepted.\n'
+            '\n'
+            '3. Unlike in Standard C, exactly two hex digits are required.\n'
+            '\n'
+            '4. In a bytes literal, hexadecimal and octal escapes denote the '
             'byte\n'
             '   with the given value. In a string literal, these escapes '
             'denote a\n'
             '   Unicode character with the given value.\n'
             '\n'
-            '4. Changed in version 3.3: Support for name aliases [1] has been\n'
+            '5. Changed in version 3.3: Support for name aliases [1] has been\n'
             '   added.\n'
             '\n'
-            '5. Exactly four hex digits are required.\n'
+            '6. Exactly four hex digits are required.\n'
             '\n'
-            '6. Any Unicode character can be encoded this way.  Exactly eight '
+            '7. Any Unicode character can be encoded this way.  Exactly eight '
             'hex\n'
             '   digits are required.\n'
             '\n'
@@ -12428,10 +12460,10 @@
         'exception.  For an except clause with an expression, that expression\n'
         'is evaluated, and the clause matches the exception if the resulting\n'
         'object is “compatible” with the exception.  An object is compatible\n'
-        'with an exception if it is the class or a base class of the '
-        'exception\n'
-        'object, or a tuple containing an item that is the class or a base\n'
-        'class of the exception object.\n'
+        'with an exception if the object is the class or a *non-virtual base\n'
+        'class* of the exception object, or a tuple containing an item that '
+        'is\n'
+        'the class or a non-virtual base class of the exception object.\n'
         '\n'
         'If no except clause matches the exception, the search for an '
         'exception\n'
@@ -12770,7 +12802,7 @@
           '         points. All the code points in the range "U+0000 - '
           'U+10FFFF"\n'
           '         can be represented in a string.  Python doesn’t have a '
-          '*char*\n'
+          'char\n'
           '         type; instead, every code point in the string is '
           'represented\n'
           '         as a string object with length "1".  The built-in '
@@ -13719,25 +13751,11 @@
                  'dictionaries or\n'
                  'other mutable types (that are compared by value rather than '
                  'by object\n'
-                 'identity) may not be used as keys.  Numeric types used for '
-                 'keys obey\n'
-                 'the normal rules for numeric comparison: if two numbers '
-                 'compare equal\n'
-                 '(such as "1" and "1.0") then they can be used '
-                 'interchangeably to index\n'
-                 'the same dictionary entry.  (Note however, that since '
-                 'computers store\n'
-                 'floating-point numbers as approximations it is usually '
-                 'unwise to use\n'
-                 'them as dictionary keys.)\n'
-                 '\n'
-                 'Dictionaries can be created by placing a comma-separated '
-                 'list of "key:\n'
-                 'value" pairs within braces, for example: "{\'jack\': 4098, '
-                 "'sjoerd':\n"
-                 '4127}" or "{4098: \'jack\', 4127: \'sjoerd\'}", or by the '
-                 '"dict"\n'
-                 'constructor.\n'
+                 'identity) may not be used as keys. Values that compare equal '
+                 '(such as\n'
+                 '"1", "1.0", and "True") can be used interchangeably to index '
+                 'the same\n'
+                 'dictionary entry.\n'
                  '\n'
                  'class dict(**kwargs)\n'
                  'class dict(mapping, **kwargs)\n'
@@ -14144,7 +14162,7 @@
                  '   New in version 3.10.\n'
                  '\n'
                  'Keys views are set-like since their entries are unique and '
-                 'hashable.\n'
+                 '*hashable*.\n'
                  'If all values are hashable, so that "(key, value)" pairs are '
                  'unique\n'
                  'and hashable, then the items view is also set-like.  (Values '
@@ -14193,8 +14211,7 @@
                  '   >>> # get back a read-only proxy for the original '
                  'dictionary\n'
                  '   >>> values.mapping\n'
-                 "   mappingproxy({'eggs': 2, 'sausage': 1, 'bacon': 1, "
-                 "'spam': 500})\n"
+                 "   mappingproxy({'bacon': 1, 'spam': 500})\n"
                  "   >>> values.mapping['spam']\n"
                  '   500\n',
  'typesmethods': 'Methods\n'
@@ -15240,7 +15257,7 @@
          '     returns without an error, then "__exit__()" will always be\n'
          '     called. Thus, if an error occurs during the assignment to the\n'
          '     target list, it will be treated the same as an error occurring\n'
-         '     within the suite would be. See step 6 below.\n'
+         '     within the suite would be. See step 7 below.\n'
          '\n'
          '6. The suite is executed.\n'
          '\n'
diff --git a/common/py3-stdlib/queue.py b/common/py3-stdlib/queue.py
index 10dbcbc..55f5008 100644
--- a/common/py3-stdlib/queue.py
+++ b/common/py3-stdlib/queue.py
@@ -298,7 +298,7 @@
     def put_nowait(self, item):
         '''Put an item into the queue without blocking.
 
-        This is exactly equivalent to `put(item)` and is only provided
+        This is exactly equivalent to `put(item, block=False)` and is only provided
         for compatibility with the Queue class.
         '''
         return self.put(item, block=False)
diff --git a/common/py3-stdlib/runpy.py b/common/py3-stdlib/runpy.py
index caba121..c7d3d8c 100644
--- a/common/py3-stdlib/runpy.py
+++ b/common/py3-stdlib/runpy.py
@@ -198,9 +198,24 @@
 
 def run_module(mod_name, init_globals=None,
                run_name=None, alter_sys=False):
-    """Execute a module's code without importing it
+    """Execute a module's code without importing it.
 
-       Returns the resulting top level namespace dictionary
+       mod_name -- an absolute module name or package name.
+
+       Optional arguments:
+       init_globals -- dictionary used to pre-populate the module’s
+       globals dictionary before the code is executed.
+
+       run_name -- if not None, this will be used for setting __name__;
+       otherwise, __name__ will be set to mod_name + '__main__' if the
+       named module is a package and to just mod_name otherwise.
+
+       alter_sys -- if True, sys.argv[0] is updated with the value of
+       __file__ and sys.modules[__name__] is updated with a temporary
+       module object for the module being executed. Both are
+       restored to their original values before the function returns.
+
+       Returns the resulting module globals dictionary.
     """
     mod_name, mod_spec, code = _get_module_details(mod_name)
     if run_name is None:
@@ -243,14 +258,19 @@
     return code, fname
 
 def run_path(path_name, init_globals=None, run_name=None):
-    """Execute code located at the specified filesystem location
+    """Execute code located at the specified filesystem location.
 
-       Returns the resulting top level namespace dictionary
+       path_name -- filesystem location of a Python script, zipfile,
+       or directory containing a top level __main__.py script.
 
-       The file path may refer directly to a Python script (i.e.
-       one that could be directly executed with execfile) or else
-       it may refer to a zipfile or directory containing a top
-       level __main__.py script.
+       Optional arguments:
+       init_globals -- dictionary used to pre-populate the module’s
+       globals dictionary before the code is executed.
+
+       run_name -- if not None, this will be used to set __name__;
+       otherwise, '<run_path>' will be used for __name__.
+
+       Returns the resulting module globals dictionary.
     """
     if run_name is None:
         run_name = "<run_path>"
diff --git a/common/py3-stdlib/shutil.py b/common/py3-stdlib/shutil.py
index 37bf98d..b7bffa3 100644
--- a/common/py3-stdlib/shutil.py
+++ b/common/py3-stdlib/shutil.py
@@ -487,12 +487,13 @@
                     # otherwise let the copy occur. copy2 will raise an error
                     if srcentry.is_dir():
                         copytree(srcobj, dstname, symlinks, ignore,
-                                 copy_function, dirs_exist_ok=dirs_exist_ok)
+                                 copy_function, ignore_dangling_symlinks,
+                                 dirs_exist_ok)
                     else:
                         copy_function(srcobj, dstname)
             elif srcentry.is_dir():
                 copytree(srcobj, dstname, symlinks, ignore, copy_function,
-                         dirs_exist_ok=dirs_exist_ok)
+                         ignore_dangling_symlinks, dirs_exist_ok)
             else:
                 # Will raise a SpecialFileError for unsupported file types
                 copy_function(srcobj, dstname)
@@ -516,9 +517,6 @@
              ignore_dangling_symlinks=False, dirs_exist_ok=False):
     """Recursively copy a directory tree and return the destination directory.
 
-    dirs_exist_ok dictates whether to raise an exception in case dst or any
-    missing parent directory already exists.
-
     If exception(s) occur, an Error is raised with a list of reasons.
 
     If the optional symlinks flag is true, symbolic links in the
@@ -549,6 +547,11 @@
     destination path as arguments. By default, copy2() is used, but any
     function that supports the same signature (like copy()) can be used.
 
+    If dirs_exist_ok is false (the default) and `dst` already exists, a
+    `FileExistsError` is raised. If `dirs_exist_ok` is true, the copying
+    operation will continue if it encounters existing directories, and files
+    within the `dst` tree will be overwritten by corresponding files from the
+    `src` tree.
     """
     sys.audit("shutil.copytree", src, dst)
     with os.scandir(src) as itr:
@@ -885,7 +888,7 @@
     return None
 
 def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0,
-                  owner=None, group=None, logger=None):
+                  owner=None, group=None, logger=None, root_dir=None):
     """Create a (possibly compressed) tar file from all the files under
     'base_dir'.
 
@@ -942,14 +945,20 @@
 
     if not dry_run:
         tar = tarfile.open(archive_name, 'w|%s' % tar_compression)
+        arcname = base_dir
+        if root_dir is not None:
+            base_dir = os.path.join(root_dir, base_dir)
         try:
-            tar.add(base_dir, filter=_set_uid_gid)
+            tar.add(base_dir, arcname, filter=_set_uid_gid)
         finally:
             tar.close()
 
+    if root_dir is not None:
+        archive_name = os.path.abspath(archive_name)
     return archive_name
 
-def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None):
+def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0,
+                  logger=None, owner=None, group=None, root_dir=None):
     """Create a zip file from all the files under 'base_dir'.
 
     The output zip file will be named 'base_name' + ".zip".  Returns the
@@ -973,42 +982,60 @@
     if not dry_run:
         with zipfile.ZipFile(zip_filename, "w",
                              compression=zipfile.ZIP_DEFLATED) as zf:
-            path = os.path.normpath(base_dir)
-            if path != os.curdir:
-                zf.write(path, path)
+            arcname = os.path.normpath(base_dir)
+            if root_dir is not None:
+                base_dir = os.path.join(root_dir, base_dir)
+            base_dir = os.path.normpath(base_dir)
+            if arcname != os.curdir:
+                zf.write(base_dir, arcname)
                 if logger is not None:
-                    logger.info("adding '%s'", path)
+                    logger.info("adding '%s'", base_dir)
             for dirpath, dirnames, filenames in os.walk(base_dir):
+                arcdirpath = dirpath
+                if root_dir is not None:
+                    arcdirpath = os.path.relpath(arcdirpath, root_dir)
+                arcdirpath = os.path.normpath(arcdirpath)
                 for name in sorted(dirnames):
-                    path = os.path.normpath(os.path.join(dirpath, name))
-                    zf.write(path, path)
+                    path = os.path.join(dirpath, name)
+                    arcname = os.path.join(arcdirpath, name)
+                    zf.write(path, arcname)
                     if logger is not None:
                         logger.info("adding '%s'", path)
                 for name in filenames:
-                    path = os.path.normpath(os.path.join(dirpath, name))
+                    path = os.path.join(dirpath, name)
+                    path = os.path.normpath(path)
                     if os.path.isfile(path):
-                        zf.write(path, path)
+                        arcname = os.path.join(arcdirpath, name)
+                        zf.write(path, arcname)
                         if logger is not None:
                             logger.info("adding '%s'", path)
 
+    if root_dir is not None:
+        zip_filename = os.path.abspath(zip_filename)
     return zip_filename
 
+# Maps the name of the archive format to a tuple containing:
+# * the archiving function
+# * extra keyword arguments
+# * description
+# * does it support the root_dir argument?
 _ARCHIVE_FORMATS = {
-    'tar':   (_make_tarball, [('compress', None)], "uncompressed tar file"),
+    'tar':   (_make_tarball, [('compress', None)],
+              "uncompressed tar file", True),
 }
 
 if _ZLIB_SUPPORTED:
     _ARCHIVE_FORMATS['gztar'] = (_make_tarball, [('compress', 'gzip')],
-                                "gzip'ed tar-file")
-    _ARCHIVE_FORMATS['zip'] = (_make_zipfile, [], "ZIP file")
+                                "gzip'ed tar-file", True)
+    _ARCHIVE_FORMATS['zip'] = (_make_zipfile, [], "ZIP file", True)
 
 if _BZ2_SUPPORTED:
     _ARCHIVE_FORMATS['bztar'] = (_make_tarball, [('compress', 'bzip2')],
-                                "bzip2'ed tar-file")
+                                "bzip2'ed tar-file", True)
 
 if _LZMA_SUPPORTED:
     _ARCHIVE_FORMATS['xztar'] = (_make_tarball, [('compress', 'xz')],
-                                "xz'ed tar-file")
+                                "xz'ed tar-file", True)
 
 def get_archive_formats():
     """Returns a list of supported formats for archiving and unarchiving.
@@ -1039,7 +1066,7 @@
         if not isinstance(element, (tuple, list)) or len(element) !=2:
             raise TypeError('extra_args elements are : (arg_name, value)')
 
-    _ARCHIVE_FORMATS[name] = (function, extra_args, description)
+    _ARCHIVE_FORMATS[name] = (function, extra_args, description, False)
 
 def unregister_archive_format(name):
     del _ARCHIVE_FORMATS[name]
@@ -1063,36 +1090,40 @@
     uses the current owner and group.
     """
     sys.audit("shutil.make_archive", base_name, format, root_dir, base_dir)
-    save_cwd = os.getcwd()
-    if root_dir is not None:
-        if logger is not None:
-            logger.debug("changing into '%s'", root_dir)
-        base_name = os.path.abspath(base_name)
-        if not dry_run:
-            os.chdir(root_dir)
-
-    if base_dir is None:
-        base_dir = os.curdir
-
-    kwargs = {'dry_run': dry_run, 'logger': logger}
-
     try:
         format_info = _ARCHIVE_FORMATS[format]
     except KeyError:
         raise ValueError("unknown archive format '%s'" % format) from None
 
+    kwargs = {'dry_run': dry_run, 'logger': logger,
+              'owner': owner, 'group': group}
+
     func = format_info[0]
     for arg, val in format_info[1]:
         kwargs[arg] = val
 
-    if format != 'zip':
-        kwargs['owner'] = owner
-        kwargs['group'] = group
+    if base_dir is None:
+        base_dir = os.curdir
+
+    support_root_dir = format_info[3]
+    save_cwd = None
+    if root_dir is not None:
+        if support_root_dir:
+            # Support path-like base_name here for backwards-compatibility.
+            base_name = os.fspath(base_name)
+            kwargs['root_dir'] = root_dir
+        else:
+            save_cwd = os.getcwd()
+            if logger is not None:
+                logger.debug("changing into '%s'", root_dir)
+            base_name = os.path.abspath(base_name)
+            if not dry_run:
+                os.chdir(root_dir)
 
     try:
         filename = func(base_name, base_dir, **kwargs)
     finally:
-        if root_dir is not None:
+        if save_cwd is not None:
             if logger is not None:
                 logger.debug("changing back to '%s'", save_cwd)
             os.chdir(save_cwd)
@@ -1205,6 +1236,11 @@
     finally:
         tarobj.close()
 
+# Maps the name of the unpack format to a tuple containing:
+# * extensions
+# * the unpacking function
+# * extra keyword arguments
+# * description
 _UNPACK_FORMATS = {
     'tar':   (['.tar'], _unpack_tarfile, [], "uncompressed tar file"),
     'zip':   (['.zip'], _unpack_zipfile, [], "ZIP file"),
diff --git a/common/py3-stdlib/smtpd.py b/common/py3-stdlib/smtpd.py
index bc43331..963e0a7 100755
--- a/common/py3-stdlib/smtpd.py
+++ b/common/py3-stdlib/smtpd.py
@@ -93,7 +93,8 @@
 ]
 
 warn(
-    'The smtpd module is deprecated and unmaintained.  Please see aiosmtpd '
+    'The smtpd module is deprecated and unmaintained and will be removed '
+    'in Python 3.12.  Please see aiosmtpd '
     '(https://aiosmtpd.readthedocs.io/) for the recommended replacement.',
     DeprecationWarning,
     stacklevel=2)
diff --git a/common/py3-stdlib/socket.py b/common/py3-stdlib/socket.py
old mode 100755
new mode 100644
index 63ba0ac..3796629
--- a/common/py3-stdlib/socket.py
+++ b/common/py3-stdlib/socket.py
@@ -783,11 +783,11 @@
 
     First the hostname returned by gethostbyaddr() is checked, then
     possibly existing aliases. In case no FQDN is available and `name`
-    was given, it is returned unchanged. If `name` was empty or '0.0.0.0',
+    was given, it is returned unchanged. If `name` was empty, '0.0.0.0' or '::',
     hostname from gethostname() is returned.
     """
     name = name.strip()
-    if not name or name == '0.0.0.0':
+    if not name or name in ('0.0.0.0', '::'):
         name = gethostname()
     try:
         hostname, aliases, ipaddrs = gethostbyaddr(name)
@@ -902,7 +902,7 @@
         # address, effectively preventing this one from accepting
         # connections. Also, it may set the process in a state where
         # it'll no longer respond to any signals or graceful kills.
-        # See: msdn2.microsoft.com/en-us/library/ms740621(VS.85).aspx
+        # See: https://learn.microsoft.com/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse
         if os.name not in ('nt', 'cygwin') and \
                 hasattr(_socket, 'SO_REUSEADDR'):
             try:
diff --git a/common/py3-stdlib/sqlite3/__init__.py b/common/py3-stdlib/sqlite3/__init__.py
index 0dedf18..5a2dbd3 100644
--- a/common/py3-stdlib/sqlite3/__init__.py
+++ b/common/py3-stdlib/sqlite3/__init__.py
@@ -21,7 +21,7 @@
 # 3. This notice may not be removed or altered from any source distribution.
 
 """
-The sqlite3 extension module provides a DB-API 2.0 (PEP 249) compilant
+The sqlite3 extension module provides a DB-API 2.0 (PEP 249) compliant
 interface to the SQLite library, and requires SQLite 3.7.15 or newer.
 
 To use the module, start by creating a database Connection object:
diff --git a/common/py3-stdlib/sqlite3/dump.py b/common/py3-stdlib/sqlite3/dump.py
index de9c368..07b9da1 100644
--- a/common/py3-stdlib/sqlite3/dump.py
+++ b/common/py3-stdlib/sqlite3/dump.py
@@ -28,9 +28,16 @@
             ORDER BY "name"
         """
     schema_res = cu.execute(q)
+    sqlite_sequence = []
     for table_name, type, sql in schema_res.fetchall():
         if table_name == 'sqlite_sequence':
-            yield('DELETE FROM "sqlite_sequence";')
+            rows = cu.execute('SELECT * FROM "sqlite_sequence";').fetchall()
+            sqlite_sequence = ['DELETE FROM "sqlite_sequence"']
+            sqlite_sequence += [
+                f'INSERT INTO "sqlite_sequence" VALUES(\'{row[0]}\',{row[1]})'
+                for row in rows
+            ]
+            continue
         elif table_name == 'sqlite_stat1':
             yield('ANALYZE "sqlite_master";')
         elif table_name.startswith('sqlite_'):
@@ -67,4 +74,9 @@
     for name, type, sql in schema_res.fetchall():
         yield('{0};'.format(sql))
 
+    # gh-79009: Yield statements concerning the sqlite_sequence table at the
+    # end of the transaction.
+    for row in sqlite_sequence:
+        yield('{0};'.format(row))
+
     yield('COMMIT;')
diff --git a/common/py3-stdlib/sqlite3/test/dbapi.py b/common/py3-stdlib/sqlite3/test/dbapi.py
index e332184..a764c82 100644
--- a/common/py3-stdlib/sqlite3/test/dbapi.py
+++ b/common/py3-stdlib/sqlite3/test/dbapi.py
@@ -381,6 +381,14 @@
         self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)])
         self.assertEqual(self.cu.rowcount, 3)
 
+    @unittest.skipIf(sqlite.sqlite_version_info < (3, 35, 0),
+                     "Requires SQLite 3.35.0 or newer")
+    def test_rowcount_update_returning(self):
+        # gh-93421: rowcount is updated correctly for UPDATE...RETURNING queries
+        self.cu.execute("update test set name='bar' where name='foo' returning 1")
+        self.assertEqual(self.cu.fetchone()[0], 1)
+        self.assertEqual(self.cu.rowcount, 1)
+
     def test_total_changes(self):
         self.cu.execute("insert into test(name) values ('foo')")
         self.cu.execute("insert into test(name) values ('foo')")
diff --git a/common/py3-stdlib/sqlite3/test/dump.py b/common/py3-stdlib/sqlite3/test/dump.py
index 618a7fd..0e324ee 100644
--- a/common/py3-stdlib/sqlite3/test/dump.py
+++ b/common/py3-stdlib/sqlite3/test/dump.py
@@ -3,6 +3,7 @@
 import unittest
 import sqlite3 as sqlite
 
+
 class DumpTests(unittest.TestCase):
     def setUp(self):
         self.cx = sqlite.connect(":memory:")
@@ -49,6 +50,51 @@
         [self.assertEqual(expected_sqls[i], actual_sqls[i])
             for i in range(len(expected_sqls))]
 
+    def test_dump_autoincrement(self):
+        expected = [
+            'CREATE TABLE "t1" (id integer primary key autoincrement);',
+            'INSERT INTO "t1" VALUES(NULL);',
+            'CREATE TABLE "t2" (id integer primary key autoincrement);',
+        ]
+        self.cu.executescript("".join(expected))
+
+        # the NULL value should now be automatically be set to 1
+        expected[1] = expected[1].replace("NULL", "1")
+        expected.insert(0, "BEGIN TRANSACTION;")
+        expected.extend([
+            'DELETE FROM "sqlite_sequence";',
+            'INSERT INTO "sqlite_sequence" VALUES(\'t1\',1);',
+            'COMMIT;',
+        ])
+
+        actual = [stmt for stmt in self.cx.iterdump()]
+        self.assertEqual(expected, actual)
+
+    def test_dump_autoincrement_create_new_db(self):
+        self.cu.execute("BEGIN TRANSACTION")
+        self.cu.execute("CREATE TABLE t1 (id integer primary key autoincrement)")
+        self.cu.execute("CREATE TABLE t2 (id integer primary key autoincrement)")
+        self.cu.executemany("INSERT INTO t1 VALUES(?)", ((None,) for _ in range(9)))
+        self.cu.executemany("INSERT INTO t2 VALUES(?)", ((None,) for _ in range(4)))
+        self.cx.commit()
+
+        cx2 = sqlite.connect(":memory:")
+        query = "".join(self.cx.iterdump())
+        cx2.executescript(query)
+        cu2 = cx2.cursor()
+
+        dataset = (
+            ("t1", 9),
+            ("t2", 4),
+        )
+        for table, seq in dataset:
+            with self.subTest(table=table, seq=seq):
+                res = cu2.execute("""
+                    SELECT "seq" FROM "sqlite_sequence" WHERE "name" == ?
+                """, (table,))
+                rows = res.fetchall()
+                self.assertEqual(rows[0][0], seq)
+
     def test_unorderable_row(self):
         # iterdump() should be able to cope with unorderable row types (issue #15545)
         class UnorderableRow:
diff --git a/common/py3-stdlib/sqlite3/test/factory.py b/common/py3-stdlib/sqlite3/test/factory.py
index 8764284..40a290f 100644
--- a/common/py3-stdlib/sqlite3/test/factory.py
+++ b/common/py3-stdlib/sqlite3/test/factory.py
@@ -155,8 +155,14 @@
         """Checks if the row object is iterable"""
         self.con.row_factory = sqlite.Row
         row = self.con.execute("select 1 as a, 2 as b").fetchone()
-        for col in row:
-            pass
+
+        # Is iterable in correct order and produces valid results:
+        items = [col for col in row]
+        self.assertEqual(items, [1, 2])
+
+        # Is iterable the second time:
+        items = [col for col in row]
+        self.assertEqual(items, [1, 2])
 
     def test_sqlite_row_as_tuple(self):
         """Checks if the row object can be converted to a tuple"""
diff --git a/common/py3-stdlib/sqlite3/test/hooks.py b/common/py3-stdlib/sqlite3/test/hooks.py
index 8c60bdc..97121ee 100644
--- a/common/py3-stdlib/sqlite3/test/hooks.py
+++ b/common/py3-stdlib/sqlite3/test/hooks.py
@@ -20,6 +20,7 @@
 #    misrepresented as being the original software.
 # 3. This notice may not be removed or altered from any source distribution.
 
+import contextlib
 import unittest
 import sqlite3 as sqlite
 
@@ -200,6 +201,16 @@
         self.assertEqual(action, 0, "progress handler was not cleared")
 
 class TraceCallbackTests(unittest.TestCase):
+    @contextlib.contextmanager
+    def check_stmt_trace(self, cx, expected):
+        try:
+            traced = []
+            cx.set_trace_callback(lambda stmt: traced.append(stmt))
+            yield
+        finally:
+            self.assertEqual(traced, expected)
+            cx.set_trace_callback(None)
+
     def test_trace_callback_used(self):
         """
         Test that the trace callback is invoked once it is set.
@@ -261,6 +272,21 @@
         cur.execute(queries[1])
         self.assertEqual(traced_statements, queries)
 
+    def test_trace_expanded_sql(self):
+        expected = [
+            "create table t(t)",
+            "BEGIN ",
+            "insert into t values(0)",
+            "insert into t values(1)",
+            "insert into t values(2)",
+            "COMMIT",
+        ]
+        cx = sqlite.connect(":memory:")
+        with self.check_stmt_trace(cx, expected):
+            with cx:
+                cx.execute("create table t(t)")
+                cx.executemany("insert into t values(?)", ((v,) for v in range(3)))
+
 
 def suite():
     tests = [
diff --git a/common/py3-stdlib/sqlite3/test/regression.py b/common/py3-stdlib/sqlite3/test/regression.py
index 70d0ff9..8937f9f 100644
--- a/common/py3-stdlib/sqlite3/test/regression.py
+++ b/common/py3-stdlib/sqlite3/test/regression.py
@@ -27,6 +27,9 @@
 import functools
 from test import support
 
+from unittest.mock import patch
+
+
 class RegressionTests(unittest.TestCase):
     def setUp(self):
         self.con = sqlite.connect(":memory:")
@@ -415,9 +418,46 @@
         self.assertEqual(val, b'')
 
 
+class RecursiveUseOfCursors(unittest.TestCase):
+    # GH-80254: sqlite3 should not segfault for recursive use of cursors.
+    msg = "Recursive use of cursors not allowed"
+
+    def setUp(self):
+        self.con = sqlite.connect(":memory:",
+                                  detect_types=sqlite.PARSE_COLNAMES)
+        self.cur = self.con.cursor()
+        self.cur.execute("create table test(x foo)")
+        self.cur.executemany("insert into test(x) values (?)",
+                             [("foo",), ("bar",)])
+
+    def tearDown(self):
+        self.cur.close()
+        self.con.close()
+
+    def test_recursive_cursor_init(self):
+        conv = lambda x: self.cur.__init__(self.con)
+        with patch.dict(sqlite.converters, {"INIT": conv}):
+            with self.assertRaisesRegex(sqlite.ProgrammingError, self.msg):
+                self.cur.execute(f'select x as "x [INIT]", x from test')
+
+    def test_recursive_cursor_close(self):
+        conv = lambda x: self.cur.close()
+        with patch.dict(sqlite.converters, {"CLOSE": conv}):
+            with self.assertRaisesRegex(sqlite.ProgrammingError, self.msg):
+                self.cur.execute(f'select x as "x [CLOSE]", x from test')
+
+    def test_recursive_cursor_fetch(self):
+        conv = lambda x, l=[]: self.cur.fetchone() if l else l.append(None)
+        with patch.dict(sqlite.converters, {"ITER": conv}):
+            self.cur.execute(f'select x as "x [ITER]", x from test')
+            with self.assertRaisesRegex(sqlite.ProgrammingError, self.msg):
+                self.cur.fetchall()
+
+
 def suite():
     tests = [
-        RegressionTests
+        RegressionTests,
+        RecursiveUseOfCursors,
     ]
     return unittest.TestSuite(
         [unittest.TestLoader().loadTestsFromTestCase(t) for t in tests]
diff --git a/common/py3-stdlib/sqlite3/test/transactions.py b/common/py3-stdlib/sqlite3/test/transactions.py
index 8028490..4ebc7fb 100644
--- a/common/py3-stdlib/sqlite3/test/transactions.py
+++ b/common/py3-stdlib/sqlite3/test/transactions.py
@@ -23,33 +23,31 @@
 import os, unittest
 import sqlite3 as sqlite
 
-def get_db_path():
-    return "sqlite_testdb"
+from test.support import LOOPBACK_TIMEOUT
+from test.support.os_helper import TESTFN, unlink
+
+
+TIMEOUT = LOOPBACK_TIMEOUT / 10
+
 
 class TransactionTests(unittest.TestCase):
     def setUp(self):
-        try:
-            os.remove(get_db_path())
-        except OSError:
-            pass
-
-        self.con1 = sqlite.connect(get_db_path(), timeout=0.1)
+        self.con1 = sqlite.connect(TESTFN, timeout=TIMEOUT)
         self.cur1 = self.con1.cursor()
 
-        self.con2 = sqlite.connect(get_db_path(), timeout=0.1)
+        self.con2 = sqlite.connect(TESTFN, timeout=TIMEOUT)
         self.cur2 = self.con2.cursor()
 
     def tearDown(self):
-        self.cur1.close()
-        self.con1.close()
-
-        self.cur2.close()
-        self.con2.close()
-
         try:
-            os.unlink(get_db_path())
-        except OSError:
-            pass
+            self.cur1.close()
+            self.con1.close()
+
+            self.cur2.close()
+            self.con2.close()
+
+        finally:
+            unlink(TESTFN)
 
     def test_dml_does_not_auto_commit_before(self):
         self.cur1.execute("create table test(i)")
diff --git a/common/py3-stdlib/sre_compile.py b/common/py3-stdlib/sre_compile.py
index c6398bf..aed752d 100644
--- a/common/py3-stdlib/sre_compile.py
+++ b/common/py3-stdlib/sre_compile.py
@@ -52,6 +52,22 @@
     (0x3c2, 0x3c3), # ςσ
     # GREEK SMALL LETTER PHI, GREEK PHI SYMBOL
     (0x3c6, 0x3d5), # φϕ
+    # CYRILLIC SMALL LETTER VE, CYRILLIC SMALL LETTER ROUNDED VE
+    (0x432, 0x1c80), # вᲀ
+    # CYRILLIC SMALL LETTER DE, CYRILLIC SMALL LETTER LONG-LEGGED DE
+    (0x434, 0x1c81), # дᲁ
+    # CYRILLIC SMALL LETTER O, CYRILLIC SMALL LETTER NARROW O
+    (0x43e, 0x1c82), # оᲂ
+    # CYRILLIC SMALL LETTER ES, CYRILLIC SMALL LETTER WIDE ES
+    (0x441, 0x1c83), # сᲃ
+    # CYRILLIC SMALL LETTER TE, CYRILLIC SMALL LETTER TALL TE, CYRILLIC SMALL LETTER THREE-LEGGED TE
+    (0x442, 0x1c84, 0x1c85), # тᲄᲅ
+    # CYRILLIC SMALL LETTER HARD SIGN, CYRILLIC SMALL LETTER TALL HARD SIGN
+    (0x44a, 0x1c86), # ъᲆ
+    # CYRILLIC SMALL LETTER YAT, CYRILLIC SMALL LETTER TALL YAT
+    (0x463, 0x1c87), # ѣᲇ
+    # CYRILLIC SMALL LETTER UNBLENDED UK, CYRILLIC SMALL LETTER MONOGRAPH UK
+    (0x1c88, 0xa64b), # ᲈꙋ
     # LATIN SMALL LETTER S WITH DOT ABOVE, LATIN SMALL LETTER LONG S WITH DOT ABOVE
     (0x1e61, 0x1e9b), # ṡẛ
     # LATIN SMALL LIGATURE LONG S T, LATIN SMALL LIGATURE ST
@@ -320,11 +336,19 @@
                     charmap += b'\0' * 0xff00
                     continue
                 # Character set contains non-BMP character codes.
+                # For range, all BMP characters in the range are already
+                # proceeded.
                 if fixup:
                     hascased = True
-                    # There are only two ranges of cased non-BMP characters:
-                    # 10400-1044F (Deseret) and 118A0-118DF (Warang Citi),
-                    # and for both ranges RANGE_UNI_IGNORE works.
+                    # For now, IN_UNI_IGNORE+LITERAL and
+                    # IN_UNI_IGNORE+RANGE_UNI_IGNORE work for all non-BMP
+                    # characters, because two characters (at least one of
+                    # which is not in the BMP) match case-insensitively
+                    # if and only if:
+                    # 1) c1.lower() == c2.lower()
+                    # 2) c1.lower() == c2 or c1.lower().upper() == c2
+                    # Also, both c.lower() and c.lower().upper() are single
+                    # characters for every non-BMP character.
                     if op is RANGE:
                         op = RANGE_UNI_IGNORE
                 tail.append((op, av))
diff --git a/common/py3-stdlib/sre_constants.py b/common/py3-stdlib/sre_constants.py
index 8e613cb..db3ca51 100644
--- a/common/py3-stdlib/sre_constants.py
+++ b/common/py3-stdlib/sre_constants.py
@@ -62,6 +62,8 @@
     def __repr__(self):
         return self.name
 
+    __reduce__ = None
+
 MAXREPEAT = _NamedIntConstant(MAXREPEAT, 'MAXREPEAT')
 
 def _makecodes(names):
diff --git a/common/py3-stdlib/sre_parse.py b/common/py3-stdlib/sre_parse.py
index 8311916..20a6025 100644
--- a/common/py3-stdlib/sre_parse.py
+++ b/common/py3-stdlib/sre_parse.py
@@ -78,6 +78,7 @@
         self.groupdict = {}
         self.groupwidths = [None]  # group 0
         self.lookbehindgroups = None
+        self.grouprefpos = {}
     @property
     def groups(self):
         return len(self.groupwidths)
@@ -330,7 +331,7 @@
             charname = source.getuntil('}', 'character name')
             try:
                 c = ord(unicodedata.lookup(charname))
-            except KeyError:
+            except (KeyError, TypeError):
                 raise source.error("undefined character name %r" % charname,
                                    len(charname) + len(r'\N{}'))
             return LITERAL, c
@@ -390,7 +391,7 @@
             charname = source.getuntil('}', 'character name')
             try:
                 c = ord(unicodedata.lookup(charname))
-            except KeyError:
+            except (KeyError, TypeError):
                 raise source.error("undefined character name %r" % charname,
                                    len(charname) + len(r'\N{}'))
             return LITERAL, c
@@ -786,6 +787,10 @@
                         if condgroup >= MAXGROUPS:
                             msg = "invalid group reference %d" % condgroup
                             raise source.error(msg, len(condname) + 1)
+                        if condgroup not in state.grouprefpos:
+                            state.grouprefpos[condgroup] = (
+                                source.tell() - len(condname) - 1
+                            )
                     state.checklookbehindgroup(condgroup, source)
                     item_yes = _parse(source, state, verbose, nested + 1)
                     if source.match("|"):
@@ -807,9 +812,11 @@
                         if not first or subpattern:
                             import warnings
                             warnings.warn(
-                                'Flags not at the start of the expression %r%s' % (
+                                'Flags not at the start of the expression %r%s'
+                                ' but at position %d' % (
                                     source.string[:20],  # truncate long regexes
                                     ' (truncated)' if len(source.string) > 20 else '',
+                                    start,
                                 ),
                                 DeprecationWarning, stacklevel=nested + 6
                             )
@@ -961,6 +968,11 @@
         assert source.next == ")"
         raise source.error("unbalanced parenthesis")
 
+    for g in p.state.grouprefpos:
+        if g >= p.state.groups:
+            msg = "invalid group reference %d" % g
+            raise error(msg, str, p.state.grouprefpos[g])
+
     if flags & SRE_FLAG_DEBUG:
         p.dump()
 
diff --git a/common/py3-stdlib/ssl.py b/common/py3-stdlib/ssl.py
index 181065d..b09d684 100644
--- a/common/py3-stdlib/ssl.py
+++ b/common/py3-stdlib/ssl.py
@@ -18,9 +18,10 @@
                           seconds past the Epoch (the time values
                           returned from time.time())
 
-  fetch_server_certificate (HOST, PORT) -- fetch the certificate provided
-                          by the server running on HOST at port PORT.  No
-                          validation of the certificate is performed.
+  get_server_certificate (addr, ssl_version, ca_certs, timeout) -- Retrieve the
+                          certificate from the server at the specified
+                          address and return it as a PEM-encoded string
+
 
 Integer constants:
 
diff --git a/common/py3-stdlib/statistics.py b/common/py3-stdlib/statistics.py
index f662453..52f1785 100644
--- a/common/py3-stdlib/statistics.py
+++ b/common/py3-stdlib/statistics.py
@@ -1265,3 +1265,9 @@
 
     def __repr__(self):
         return f'{type(self).__name__}(mu={self._mu!r}, sigma={self._sigma!r})'
+
+    def __getstate__(self):
+        return self._mu, self._sigma
+
+    def __setstate__(self, state):
+        self._mu, self._sigma = state
diff --git a/common/py3-stdlib/subprocess.py b/common/py3-stdlib/subprocess.py
index ccb46a6..f1e3d64 100644
--- a/common/py3-stdlib/subprocess.py
+++ b/common/py3-stdlib/subprocess.py
@@ -411,7 +411,8 @@
     if 'input' in kwargs and kwargs['input'] is None:
         # Explicitly passing input=None was previously equivalent to passing an
         # empty string. That is maintained here for backwards compatibility.
-        if kwargs.get('universal_newlines') or kwargs.get('text'):
+        if kwargs.get('universal_newlines') or kwargs.get('text') or kwargs.get('encoding') \
+                or kwargs.get('errors'):
             empty = ''
         else:
             empty = b''
@@ -463,7 +464,8 @@
 
     The returned instance will have attributes args, returncode, stdout and
     stderr. By default, stdout and stderr are not captured, and those attributes
-    will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them.
+    will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them,
+    or pass capture_output=True to capture both.
 
     If check is True and the exit code was non-zero, it raises a
     CalledProcessError. The CalledProcessError object will have the return code
@@ -691,7 +693,10 @@
     return False
 
 
+# These are primarily fail-safe knobs for negatives. A True value does not
+# guarantee the given libc/syscall API will be used.
 _USE_POSIX_SPAWN = _use_posix_spawn()
+_USE_VFORK = True
 
 
 class Popen:
@@ -1422,7 +1427,23 @@
             if shell:
                 startupinfo.dwFlags |= _winapi.STARTF_USESHOWWINDOW
                 startupinfo.wShowWindow = _winapi.SW_HIDE
-                comspec = os.environ.get("COMSPEC", "cmd.exe")
+                if not executable:
+                    # gh-101283: without a fully-qualified path, before Windows
+                    # checks the system directories, it first looks in the
+                    # application directory, and also the current directory if
+                    # NeedCurrentDirectoryForExePathW(ExeName) is true, so try
+                    # to avoid executing unqualified "cmd.exe".
+                    comspec = os.environ.get('ComSpec')
+                    if not comspec:
+                        system_root = os.environ.get('SystemRoot', '')
+                        comspec = os.path.join(system_root, 'System32', 'cmd.exe')
+                        if not os.path.isabs(comspec):
+                            raise FileNotFoundError('shell not found: neither %ComSpec% nor %SystemRoot% is set')
+                    if os.path.isabs(comspec):
+                        executable = comspec
+                else:
+                    comspec = executable
+
                 args = '{} /c "{}"'.format (comspec, args)
 
             if cwd is not None:
diff --git a/common/py3-stdlib/symtable.py b/common/py3-stdlib/symtable.py
index 98db1e2..e11e5ff 100644
--- a/common/py3-stdlib/symtable.py
+++ b/common/py3-stdlib/symtable.py
@@ -111,7 +111,7 @@
         return bool(self._table.children)
 
     def get_identifiers(self):
-        """Return a list of names of symbols in the table.
+        """Return a view object containing the names of symbols in the table.
         """
         return self._table.symbols.keys()
 
diff --git a/common/py3-stdlib/tabnanny.py b/common/py3-stdlib/tabnanny.py
index 7973f26..a47f5a9 100755
--- a/common/py3-stdlib/tabnanny.py
+++ b/common/py3-stdlib/tabnanny.py
@@ -23,8 +23,6 @@
 import os
 import sys
 import tokenize
-if not hasattr(tokenize, 'NL'):
-    raise ValueError("tokenize.NL doesn't exist -- tokenize module too old")
 
 __all__ = ["check", "NannyNag", "process_tokens"]
 
diff --git a/common/py3-stdlib/tarfile.py b/common/py3-stdlib/tarfile.py
index 6ada9a0..dea150e 100755
--- a/common/py3-stdlib/tarfile.py
+++ b/common/py3-stdlib/tarfile.py
@@ -1163,6 +1163,11 @@
         # header information.
         self._apply_pax_info(tarfile.pax_headers, tarfile.encoding, tarfile.errors)
 
+        # Remove redundant slashes from directories. This is to be consistent
+        # with frombuf().
+        if self.isdir():
+            self.name = self.name.rstrip("/")
+
         return self
 
     def _proc_gnulong(self, tarfile):
@@ -1185,6 +1190,11 @@
         elif self.type == GNUTYPE_LONGLINK:
             next.linkname = nts(buf, tarfile.encoding, tarfile.errors)
 
+        # Remove redundant slashes from directories. This is to be consistent
+        # with frombuf().
+        if next.isdir():
+            next.name = next.name.removesuffix("/")
+
         return next
 
     def _proc_sparse(self, tarfile):
diff --git a/common/py3-stdlib/tempfile.py b/common/py3-stdlib/tempfile.py
index 7b68212..96da930 100644
--- a/common/py3-stdlib/tempfile.py
+++ b/common/py3-stdlib/tempfile.py
@@ -203,8 +203,7 @@
                 fd = _os.open(filename, _bin_openflags, 0o600)
                 try:
                     try:
-                        with _io.open(fd, 'wb', closefd=False) as fp:
-                            fp.write(b'blat')
+                        _os.write(fd, b'blat')
                     finally:
                         _os.close(fd)
                 finally:
@@ -244,6 +243,7 @@
 def _mkstemp_inner(dir, pre, suf, flags, output_type):
     """Code common to mkstemp, TemporaryFile, and NamedTemporaryFile."""
 
+    dir = _os.path.abspath(dir)
     names = _get_candidate_names()
     if output_type is bytes:
         names = map(_os.fsencode, names)
@@ -264,7 +264,7 @@
                 continue
             else:
                 raise
-        return (fd, _os.path.abspath(file))
+        return fd, file
 
     raise FileExistsError(_errno.EEXIST,
                           "No usable temporary file name found")
@@ -550,15 +550,26 @@
     if "b" not in mode:
         encoding = _io.text_encoding(encoding)
 
-    (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags, output_type)
+    name = None
+    def opener(*args):
+        nonlocal name
+        fd, name = _mkstemp_inner(dir, prefix, suffix, flags, output_type)
+        return fd
     try:
-        file = _io.open(fd, mode, buffering=buffering,
-                        newline=newline, encoding=encoding, errors=errors)
-
-        return _TemporaryFileWrapper(file, name, delete)
-    except BaseException:
-        _os.unlink(name)
-        _os.close(fd)
+        file = _io.open(dir, mode, buffering=buffering,
+                        newline=newline, encoding=encoding, errors=errors,
+                        opener=opener)
+        try:
+            raw = getattr(file, 'buffer', file)
+            raw = getattr(raw, 'raw', raw)
+            raw.name = name
+            return _TemporaryFileWrapper(file, name, delete)
+        except:
+            file.close()
+            raise
+    except:
+        if name is not None and not (_os.name == 'nt' and delete):
+            _os.unlink(name)
         raise
 
 if _os.name != 'posix' or _sys.platform == 'cygwin':
@@ -597,9 +608,20 @@
 
         flags = _bin_openflags
         if _O_TMPFILE_WORKS:
-            try:
+            fd = None
+            def opener(*args):
+                nonlocal fd
                 flags2 = (flags | _os.O_TMPFILE) & ~_os.O_CREAT
                 fd = _os.open(dir, flags2, 0o600)
+                return fd
+            try:
+                file = _io.open(dir, mode, buffering=buffering,
+                                newline=newline, encoding=encoding,
+                                errors=errors, opener=opener)
+                raw = getattr(file, 'buffer', file)
+                raw = getattr(raw, 'raw', raw)
+                raw.name = fd
+                return file
             except IsADirectoryError:
                 # Linux kernel older than 3.11 ignores the O_TMPFILE flag:
                 # O_TMPFILE is read as O_DIRECTORY. Trying to open a directory
@@ -616,24 +638,25 @@
                 # fails with NotADirectoryError, because O_TMPFILE is read as
                 # O_DIRECTORY.
                 pass
-            else:
-                try:
-                    return _io.open(fd, mode, buffering=buffering,
-                                    newline=newline, encoding=encoding,
-                                    errors=errors)
-                except:
-                    _os.close(fd)
-                    raise
             # Fallback to _mkstemp_inner().
 
-        (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags, output_type)
-        try:
-            _os.unlink(name)
-            return _io.open(fd, mode, buffering=buffering,
-                            newline=newline, encoding=encoding, errors=errors)
-        except:
-            _os.close(fd)
-            raise
+        fd = None
+        def opener(*args):
+            nonlocal fd
+            fd, name = _mkstemp_inner(dir, prefix, suffix, flags, output_type)
+            try:
+                _os.unlink(name)
+            except BaseException as e:
+                _os.close(fd)
+                raise
+            return fd
+        file = _io.open(dir, mode, buffering=buffering,
+                        newline=newline, encoding=encoding, errors=errors,
+                        opener=opener)
+        raw = getattr(file, 'buffer', file)
+        raw = getattr(raw, 'raw', raw)
+        raw.name = fd
+        return file
 
 class SpooledTemporaryFile:
     """Temporary file wrapper, specialized to switch from BytesIO
diff --git a/common/py3-stdlib/threading.py b/common/py3-stdlib/threading.py
index 2d89742..62f49c0 100644
--- a/common/py3-stdlib/threading.py
+++ b/common/py3-stdlib/threading.py
@@ -368,14 +368,21 @@
         """
         if not self._is_owned():
             raise RuntimeError("cannot notify on un-acquired lock")
-        all_waiters = self._waiters
-        waiters_to_notify = _deque(_islice(all_waiters, n))
-        if not waiters_to_notify:
-            return
-        for waiter in waiters_to_notify:
-            waiter.release()
+        waiters = self._waiters
+        while waiters and n > 0:
+            waiter = waiters[0]
             try:
-                all_waiters.remove(waiter)
+                waiter.release()
+            except RuntimeError:
+                # gh-92530: The previous call of notify() released the lock,
+                # but was interrupted before removing it from the queue.
+                # It can happen if a signal handler raises an exception,
+                # like CTRL+C which raises KeyboardInterrupt.
+                pass
+            else:
+                n -= 1
+            try:
+                waiters.remove(waiter)
             except ValueError:
                 pass
 
@@ -550,7 +557,7 @@
     def isSet(self):
         """Return true if and only if the internal flag is true.
 
-        This method is deprecated, use notify_all() instead.
+        This method is deprecated, use is_set() instead.
 
         """
         import warnings
diff --git a/common/py3-stdlib/trace.py b/common/py3-stdlib/trace.py
index 2cf3643..213e465 100755
--- a/common/py3-stdlib/trace.py
+++ b/common/py3-stdlib/trace.py
@@ -172,7 +172,7 @@
             try:
                 with open(self.infile, 'rb') as f:
                     counts, calledfuncs, callers = pickle.load(f)
-                self.update(self.__class__(counts, calledfuncs, callers))
+                self.update(self.__class__(counts, calledfuncs, callers=callers))
             except (OSError, EOFError, ValueError) as err:
                 print(("Skipping counts file %r: %s"
                                       % (self.infile, err)), file=sys.stderr)
diff --git a/common/py3-stdlib/turtle.py b/common/py3-stdlib/turtle.py
index f3b320b..d287c15 100644
--- a/common/py3-stdlib/turtle.py
+++ b/common/py3-stdlib/turtle.py
@@ -595,7 +595,6 @@
         item = self.cv.create_text(x-1, -y, text = txt, anchor = anchor[align],
                                         fill = pencolor, font = font)
         x0, y0, x1, y1 = self.cv.bbox(item)
-        self.cv.update()
         return item, x1-1
 
 ##    def _dot(self, pos, size, color):
@@ -954,7 +953,7 @@
 
 
 class TurtleScreen(TurtleScreenBase):
-    """Provides screen oriented methods like setbg etc.
+    """Provides screen oriented methods like bgcolor etc.
 
     Only relies upon the methods of TurtleScreenBase and NOT
     upon components of the underlying graphics toolkit -
@@ -3403,6 +3402,7 @@
         """
         item, end = self.screen._write(self._position, txt, align, font,
                                                           self._pencolor)
+        self._update()
         self.items.append(item)
         if self.undobuffer:
             self.undobuffer.push(("wri", item))
diff --git a/common/py3-stdlib/typing.py b/common/py3-stdlib/typing.py
index 086d0f3..03cf243 100644
--- a/common/py3-stdlib/typing.py
+++ b/common/py3-stdlib/typing.py
@@ -901,7 +901,7 @@
 
     Parameter specification variables can be introspected. e.g.:
 
-       P.__name__ == 'T'
+       P.__name__ == 'P'
        P.__bound__ == None
        P.__covariant__ == False
        P.__contravariant__ == False
@@ -1099,7 +1099,8 @@
         else:
             origin = self.__origin__
         args = tuple(self.__args__)
-        if len(args) == 1 and not isinstance(args[0], tuple):
+        if len(args) == 1 and (not isinstance(args[0], tuple) or
+                               origin is Tuple and not args[0]):
             args, = args
         return operator.getitem, (origin, args)
 
diff --git a/common/py3-stdlib/unittest/async_case.py b/common/py3-stdlib/unittest/async_case.py
index 2323119..d9c694e 100644
--- a/common/py3-stdlib/unittest/async_case.py
+++ b/common/py3-stdlib/unittest/async_case.py
@@ -148,6 +148,8 @@
             # shutdown asyncgens
             loop.run_until_complete(loop.shutdown_asyncgens())
         finally:
+            # Prevent our executor environment from leaking to future tests.
+            loop.run_until_complete(loop.shutdown_default_executor())
             asyncio.set_event_loop(None)
             loop.close()
 
diff --git a/common/py3-stdlib/unittest/case.py b/common/py3-stdlib/unittest/case.py
index 61003d0..50100e9 100644
--- a/common/py3-stdlib/unittest/case.py
+++ b/common/py3-stdlib/unittest/case.py
@@ -348,11 +348,11 @@
     # of difflib.  See #11763.
     _diffThreshold = 2**16
 
-    # Attribute used by TestSuite for classSetUp
-
-    _classSetupFailed = False
-
-    _class_cleanups = []
+    def __init_subclass__(cls, *args, **kwargs):
+        # Attribute used by TestSuite for classSetUp
+        cls._classSetupFailed = False
+        cls._class_cleanups = []
+        super().__init_subclass__(*args, **kwargs)
 
     def __init__(self, methodName='runTest'):
         """Create an instance of the class that will use the named test
diff --git a/common/py3-stdlib/unittest/main.py b/common/py3-stdlib/unittest/main.py
index e62469a..88a188c 100644
--- a/common/py3-stdlib/unittest/main.py
+++ b/common/py3-stdlib/unittest/main.py
@@ -39,7 +39,7 @@
             name = rel_path
         # on Windows both '\' and '/' are used as path
         # separators. Better to replace both than rely on os.path.sep
-        return name[:-3].replace('\\', '.').replace('/', '.')
+        return os.path.normpath(name)[:-3].replace('\\', '.').replace('/', '.')
     return name
 
 def _convert_names(names):
diff --git a/common/py3-stdlib/unittest/mock.py b/common/py3-stdlib/unittest/mock.py
index 7152f86..7453dfa 100644
--- a/common/py3-stdlib/unittest/mock.py
+++ b/common/py3-stdlib/unittest/mock.py
@@ -34,6 +34,7 @@
 from types import CodeType, ModuleType, MethodType
 from unittest.util import safe_repr
 from functools import wraps, partial
+from threading import RLock
 
 
 class InvalidSpecError(Exception):
@@ -401,6 +402,14 @@
 class NonCallableMock(Base):
     """A non-callable version of `Mock`"""
 
+    # Store a mutex as a class attribute in order to protect concurrent access
+    # to mock attributes. Using a class attribute allows all NonCallableMock
+    # instances to share the mutex for simplicity.
+    #
+    # See https://github.com/python/cpython/issues/98624 for why this is
+    # necessary.
+    _lock = RLock()
+
     def __new__(cls, /, *args, **kw):
         # every instance has its own class
         # so we can create magic methods on the
@@ -634,41 +643,42 @@
                 raise AttributeError("Mock object has no attribute %r" % name)
         elif _is_magic(name):
             raise AttributeError(name)
-        if not self._mock_unsafe:
+        if not self._mock_unsafe and (not self._mock_methods or name not in self._mock_methods):
             if name.startswith(('assert', 'assret', 'asert', 'aseert', 'assrt')):
                 raise AttributeError(
                     f"{name!r} is not a valid assertion. Use a spec "
                     f"for the mock if {name!r} is meant to be an attribute.")
 
-        result = self._mock_children.get(name)
-        if result is _deleted:
-            raise AttributeError(name)
-        elif result is None:
-            wraps = None
-            if self._mock_wraps is not None:
-                # XXXX should we get the attribute without triggering code
-                # execution?
-                wraps = getattr(self._mock_wraps, name)
+        with NonCallableMock._lock:
+            result = self._mock_children.get(name)
+            if result is _deleted:
+                raise AttributeError(name)
+            elif result is None:
+                wraps = None
+                if self._mock_wraps is not None:
+                    # XXXX should we get the attribute without triggering code
+                    # execution?
+                    wraps = getattr(self._mock_wraps, name)
 
-            result = self._get_child_mock(
-                parent=self, name=name, wraps=wraps, _new_name=name,
-                _new_parent=self
-            )
-            self._mock_children[name]  = result
-
-        elif isinstance(result, _SpecState):
-            try:
-                result = create_autospec(
-                    result.spec, result.spec_set, result.instance,
-                    result.parent, result.name
+                result = self._get_child_mock(
+                    parent=self, name=name, wraps=wraps, _new_name=name,
+                    _new_parent=self
                 )
-            except InvalidSpecError:
-                target_name = self.__dict__['_mock_name'] or self
-                raise InvalidSpecError(
-                    f'Cannot autospec attr {name!r} from target '
-                    f'{target_name!r} as it has already been mocked out. '
-                    f'[target={self!r}, attr={result.spec!r}]')
-            self._mock_children[name]  = result
+                self._mock_children[name]  = result
+
+            elif isinstance(result, _SpecState):
+                try:
+                    result = create_autospec(
+                        result.spec, result.spec_set, result.instance,
+                        result.parent, result.name
+                    )
+                except InvalidSpecError:
+                    target_name = self.__dict__['_mock_name'] or self
+                    raise InvalidSpecError(
+                        f'Cannot autospec attr {name!r} from target '
+                        f'{target_name!r} as it has already been mocked out. '
+                        f'[target={self!r}, attr={result.spec!r}]')
+                self._mock_children[name]  = result
 
         return result
 
@@ -1000,15 +1010,15 @@
 
         For non-callable mocks the callable variant will be used (rather than
         any custom subclass)."""
-        _new_name = kw.get("_new_name")
-        if _new_name in self.__dict__['_spec_asyncs']:
-            return AsyncMock(**kw)
-
         if self._mock_sealed:
             attribute = f".{kw['name']}" if "name" in kw else "()"
             mock_name = self._extract_mock_name() + attribute
             raise AttributeError(mock_name)
 
+        _new_name = kw.get("_new_name")
+        if _new_name in self.__dict__['_spec_asyncs']:
+            return AsyncMock(**kw)
+
         _type = type(self)
         if issubclass(_type, MagicMock) and _new_name in _async_method_magics:
             # Any asynchronous magic becomes an AsyncMock
@@ -1810,6 +1820,12 @@
     def __call__(self, f):
         if isinstance(f, type):
             return self.decorate_class(f)
+        if inspect.iscoroutinefunction(f):
+            return self.decorate_async_callable(f)
+        return self.decorate_callable(f)
+
+
+    def decorate_callable(self, f):
         @wraps(f)
         def _inner(*args, **kw):
             self._patch_dict()
@@ -1821,6 +1837,18 @@
         return _inner
 
 
+    def decorate_async_callable(self, f):
+        @wraps(f)
+        async def _inner(*args, **kw):
+            self._patch_dict()
+            try:
+                return await f(*args, **kw)
+            finally:
+                self._unpatch_dict()
+
+        return _inner
+
+
     def decorate_class(self, klass):
         for attr in dir(klass):
             attr_value = getattr(klass, attr)
@@ -2186,6 +2214,10 @@
         code_mock = NonCallableMock(spec_set=CodeType)
         code_mock.co_flags = inspect.CO_COROUTINE
         self.__dict__['__code__'] = code_mock
+        self.__dict__['__name__'] = 'AsyncMock'
+        self.__dict__['__defaults__'] = tuple()
+        self.__dict__['__kwdefaults__'] = {}
+        self.__dict__['__annotations__'] = None
 
     async def _execute_mock_call(self, /, *args, **kwargs):
         # This is nearly just like super(), except for special handling
diff --git a/common/py3-stdlib/unittest/result.py b/common/py3-stdlib/unittest/result.py
index 3da7005..5ca4c23 100644
--- a/common/py3-stdlib/unittest/result.py
+++ b/common/py3-stdlib/unittest/result.py
@@ -196,6 +196,7 @@
         ret = None
         first = True
         excs = [(exctype, value, tb)]
+        seen = {id(value)}  # Detect loops in chained exceptions.
         while excs:
             (exctype, value, tb) = excs.pop()
             # Skip test runner traceback levels
@@ -214,8 +215,9 @@
 
             if value is not None:
                 for c in (value.__cause__, value.__context__):
-                    if c is not None:
+                    if c is not None and id(c) not in seen:
                         excs.append((type(c), c, c.__traceback__))
+                        seen.add(id(c))
         return ret
 
     def _is_relevant_tb_level(self, tb):
diff --git a/common/py3-stdlib/unittest/test/test_async_case.py b/common/py3-stdlib/unittest/test/test_async_case.py
index e46b99f..a68ae86 100644
--- a/common/py3-stdlib/unittest/test/test_async_case.py
+++ b/common/py3-stdlib/unittest/test/test_async_case.py
@@ -14,65 +14,79 @@
 class TestAsyncCase(unittest.TestCase):
     maxDiff = None
 
-    def tearDown(self):
+    def setUp(self):
         # Ensure that IsolatedAsyncioTestCase instances are destroyed before
         # starting a new event loop
-        support.gc_collect()
+        self.addCleanup(support.gc_collect)
 
     def test_full_cycle(self):
+        expected = ['setUp',
+                    'asyncSetUp',
+                    'test',
+                    'asyncTearDown',
+                    'tearDown',
+                    'cleanup6',
+                    'cleanup5',
+                    'cleanup4',
+                    'cleanup3',
+                    'cleanup2',
+                    'cleanup1']
         class Test(unittest.IsolatedAsyncioTestCase):
             def setUp(self):
                 self.assertEqual(events, [])
                 events.append('setUp')
-
-            async def asyncSetUp(self):
-                self.assertEqual(events, ['setUp'])
-                events.append('asyncSetUp')
-                self.addAsyncCleanup(self.on_cleanup1)
-
-            async def test_func(self):
-                self.assertEqual(events, ['setUp',
-                                          'asyncSetUp'])
-                events.append('test')
+                self.addCleanup(self.on_cleanup1)
                 self.addAsyncCleanup(self.on_cleanup2)
 
+            async def asyncSetUp(self):
+                self.assertEqual(events, expected[:1])
+                events.append('asyncSetUp')
+                self.addCleanup(self.on_cleanup3)
+                self.addAsyncCleanup(self.on_cleanup4)
+
+            async def test_func(self):
+                self.assertEqual(events, expected[:2])
+                events.append('test')
+                self.addCleanup(self.on_cleanup5)
+                self.addAsyncCleanup(self.on_cleanup6)
+
             async def asyncTearDown(self):
-                self.assertEqual(events, ['setUp',
-                                          'asyncSetUp',
-                                          'test'])
+                self.assertEqual(events, expected[:3])
                 events.append('asyncTearDown')
 
             def tearDown(self):
-                self.assertEqual(events, ['setUp',
-                                          'asyncSetUp',
-                                          'test',
-                                          'asyncTearDown'])
+                self.assertEqual(events, expected[:4])
                 events.append('tearDown')
 
-            async def on_cleanup1(self):
-                self.assertEqual(events, ['setUp',
-                                          'asyncSetUp',
-                                          'test',
-                                          'asyncTearDown',
-                                          'tearDown',
-                                          'cleanup2'])
+            def on_cleanup1(self):
+                self.assertEqual(events, expected[:10])
                 events.append('cleanup1')
 
             async def on_cleanup2(self):
-                self.assertEqual(events, ['setUp',
-                                          'asyncSetUp',
-                                          'test',
-                                          'asyncTearDown',
-                                          'tearDown'])
+                self.assertEqual(events, expected[:9])
                 events.append('cleanup2')
 
+            def on_cleanup3(self):
+                self.assertEqual(events, expected[:8])
+                events.append('cleanup3')
+
+            async def on_cleanup4(self):
+                self.assertEqual(events, expected[:7])
+                events.append('cleanup4')
+
+            def on_cleanup5(self):
+                self.assertEqual(events, expected[:6])
+                events.append('cleanup5')
+
+            async def on_cleanup6(self):
+                self.assertEqual(events, expected[:5])
+                events.append('cleanup6')
+
         events = []
         test = Test("test_func")
         result = test.run()
         self.assertEqual(result.errors, [])
         self.assertEqual(result.failures, [])
-        expected = ['setUp', 'asyncSetUp', 'test',
-                    'asyncTearDown', 'tearDown', 'cleanup2', 'cleanup1']
         self.assertEqual(events, expected)
 
         events = []
@@ -108,6 +122,7 @@
 
         events = []
         test = Test("test_func")
+        self.addCleanup(test._tearDownAsyncioLoop)
         try:
             test.debug()
         except MyException:
@@ -143,6 +158,7 @@
 
         events = []
         test = Test("test_func")
+        self.addCleanup(test._tearDownAsyncioLoop)
         try:
             test.debug()
         except MyException:
@@ -178,6 +194,7 @@
 
         events = []
         test = Test("test_func")
+        self.addCleanup(test._tearDownAsyncioLoop)
         try:
             test.debug()
         except MyException:
@@ -219,6 +236,7 @@
 
         events = []
         test = Test("test_func")
+        self.addCleanup(test._tearDownAsyncioLoop)
         try:
             test.debug()
         except MyException:
@@ -331,6 +349,7 @@
 
         events = []
         test = Test("test_func")
+        self.addCleanup(test._tearDownAsyncioLoop)
         try:
             test.debug()
         except MyException:
diff --git a/common/py3-stdlib/unittest/test/test_result.py b/common/py3-stdlib/unittest/test/test_result.py
index c5aaba0..90484fd 100644
--- a/common/py3-stdlib/unittest/test/test_result.py
+++ b/common/py3-stdlib/unittest/test/test_result.py
@@ -275,6 +275,62 @@
         self.assertEqual(len(dropped), 1)
         self.assertIn("raise self.failureException(msg)", dropped[0])
 
+    def test_addFailure_filter_traceback_frames_chained_exception_self_loop(self):
+        class Foo(unittest.TestCase):
+            def test_1(self):
+                pass
+
+        def get_exc_info():
+            try:
+                loop = Exception("Loop")
+                loop.__cause__ = loop
+                loop.__context__ = loop
+                raise loop
+            except:
+                return sys.exc_info()
+
+        exc_info_tuple = get_exc_info()
+
+        test = Foo('test_1')
+        result = unittest.TestResult()
+        result.startTest(test)
+        result.addFailure(test, exc_info_tuple)
+        result.stopTest(test)
+
+        formatted_exc = result.failures[0][1]
+        self.assertEqual(formatted_exc.count("Exception: Loop\n"), 1)
+
+    def test_addFailure_filter_traceback_frames_chained_exception_cycle(self):
+        class Foo(unittest.TestCase):
+            def test_1(self):
+                pass
+
+        def get_exc_info():
+            try:
+                # Create two directionally opposed cycles
+                # __cause__ in one direction, __context__ in the other
+                A, B, C = Exception("A"), Exception("B"), Exception("C")
+                edges = [(C, B), (B, A), (A, C)]
+                for ex1, ex2 in edges:
+                    ex1.__cause__ = ex2
+                    ex2.__context__ = ex1
+                raise C
+            except:
+                return sys.exc_info()
+
+        exc_info_tuple = get_exc_info()
+
+        test = Foo('test_1')
+        result = unittest.TestResult()
+        result.startTest(test)
+        result.addFailure(test, exc_info_tuple)
+        result.stopTest(test)
+
+        formatted_exc = result.failures[0][1]
+        self.assertEqual(formatted_exc.count("Exception: A\n"), 1)
+        self.assertEqual(formatted_exc.count("Exception: B\n"), 1)
+        self.assertEqual(formatted_exc.count("Exception: C\n"), 1)
+
     # "addError(test, err)"
     # ...
     # "Called when the test case test raises an unexpected exception err
diff --git a/common/py3-stdlib/unittest/test/test_runner.py b/common/py3-stdlib/unittest/test/test_runner.py
index 453e6c3..0082d39 100644
--- a/common/py3-stdlib/unittest/test/test_runner.py
+++ b/common/py3-stdlib/unittest/test/test_runner.py
@@ -106,11 +106,13 @@
         class TestableTest(unittest.TestCase):
             def setUp(self):
                 ordering.append('setUp')
+                test.addCleanup(cleanup2)
                 if blowUp:
                     raise Exception('foo')
 
             def testNothing(self):
                 ordering.append('test')
+                test.addCleanup(cleanup3)
 
             def tearDown(self):
                 ordering.append('tearDown')
@@ -121,8 +123,9 @@
             ordering.append('cleanup1')
         def cleanup2():
             ordering.append('cleanup2')
+        def cleanup3():
+            ordering.append('cleanup3')
         test.addCleanup(cleanup1)
-        test.addCleanup(cleanup2)
 
         def success(some_test):
             self.assertEqual(some_test, test)
@@ -132,7 +135,7 @@
         result.addSuccess = success
 
         test.run(result)
-        self.assertEqual(ordering, ['setUp', 'test', 'tearDown',
+        self.assertEqual(ordering, ['setUp', 'test', 'tearDown', 'cleanup3',
                                     'cleanup2', 'cleanup1', 'success'])
 
         blowUp = True
@@ -140,7 +143,7 @@
         test = TestableTest('testNothing')
         test.addCleanup(cleanup1)
         test.run(result)
-        self.assertEqual(ordering, ['setUp', 'cleanup1'])
+        self.assertEqual(ordering, ['setUp', 'cleanup2', 'cleanup1'])
 
     def testTestCaseDebugExecutesCleanups(self):
         ordering = []
@@ -152,9 +155,11 @@
 
             def testNothing(self):
                 ordering.append('test')
+                self.addCleanup(cleanup3)
 
             def tearDown(self):
                 ordering.append('tearDown')
+                test.addCleanup(cleanup4)
 
         test = TestableTest('testNothing')
 
@@ -163,9 +168,14 @@
             test.addCleanup(cleanup2)
         def cleanup2():
             ordering.append('cleanup2')
+        def cleanup3():
+            ordering.append('cleanup3')
+        def cleanup4():
+            ordering.append('cleanup4')
 
         test.debug()
-        self.assertEqual(ordering, ['setUp', 'test', 'tearDown', 'cleanup1', 'cleanup2'])
+        self.assertEqual(ordering, ['setUp', 'test', 'tearDown', 'cleanup4',
+                                    'cleanup3', 'cleanup1', 'cleanup2'])
 
 
 class TestClassCleanup(unittest.TestCase):
@@ -291,13 +301,14 @@
                 ordering.append('test')
             @classmethod
             def tearDownClass(cls):
+                ordering.append('tearDownClass')
                 raise Exception('TearDownClassExc')
 
         suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest)
         with self.assertRaises(Exception) as cm:
             suite.debug()
         self.assertEqual(str(cm.exception), 'TearDownClassExc')
-        self.assertEqual(ordering, ['setUpClass', 'test'])
+        self.assertEqual(ordering, ['setUpClass', 'test', 'tearDownClass'])
         self.assertTrue(TestableTest._class_cleanups)
         TestableTest._class_cleanups.clear()
 
@@ -307,7 +318,7 @@
         with self.assertRaises(Exception) as cm:
             suite.debug()
         self.assertEqual(str(cm.exception), 'TearDownClassExc')
-        self.assertEqual(ordering, ['setUpClass', 'test'])
+        self.assertEqual(ordering, ['setUpClass', 'test', 'tearDownClass'])
         self.assertTrue(TestableTest._class_cleanups)
         TestableTest._class_cleanups.clear()
 
@@ -446,6 +457,33 @@
         self.assertEqual(ordering,
                          ['setUpClass', 'test', 'tearDownClass', 'cleanup_good'])
 
+    def test_run_nested_test(self):
+        ordering = []
+
+        class InnerTest(unittest.TestCase):
+            @classmethod
+            def setUpClass(cls):
+                ordering.append('inner setup')
+                cls.addClassCleanup(ordering.append, 'inner cleanup')
+            def test(self):
+                ordering.append('inner test')
+
+        class OuterTest(unittest.TestCase):
+            @classmethod
+            def setUpClass(cls):
+                ordering.append('outer setup')
+                cls.addClassCleanup(ordering.append, 'outer cleanup')
+            def test(self):
+                ordering.append('start outer test')
+                runTests(InnerTest)
+                ordering.append('end outer test')
+
+        runTests(OuterTest)
+        self.assertEqual(ordering, [
+                'outer setup', 'start outer test',
+                'inner setup', 'inner test', 'inner cleanup',
+                'end outer test', 'outer cleanup'])
+
 
 class TestModuleCleanUp(unittest.TestCase):
     def test_add_and_do_ModuleCleanup(self):
@@ -657,6 +695,7 @@
                 unittest.addModuleCleanup(cleanup, ordering)
             @staticmethod
             def tearDownModule():
+                ordering.append('tearDownModule')
                 raise Exception('CleanUpExc')
 
         class TestableTest(unittest.TestCase):
@@ -675,7 +714,8 @@
         self.assertEqual(result.errors[0][1].splitlines()[-1],
                          'Exception: CleanUpExc')
         self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test',
-                                    'tearDownClass', 'cleanup_good'])
+                                    'tearDownClass', 'tearDownModule',
+                                    'cleanup_good'])
         self.assertEqual(unittest.case._module_cleanups, [])
 
     def test_debug_module_executes_cleanUp(self):
@@ -729,6 +769,7 @@
                 unittest.addModuleCleanup(cleanup, ordering, blowUp=blowUp)
             @staticmethod
             def tearDownModule():
+                ordering.append('tearDownModule')
                 raise Exception('TearDownModuleExc')
 
         class TestableTest(unittest.TestCase):
@@ -748,7 +789,7 @@
             suite.debug()
         self.assertEqual(str(cm.exception), 'TearDownModuleExc')
         self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test',
-                                    'tearDownClass'])
+                                    'tearDownClass', 'tearDownModule'])
         self.assertTrue(unittest.case._module_cleanups)
         unittest.case._module_cleanups.clear()
 
@@ -759,7 +800,7 @@
             suite.debug()
         self.assertEqual(str(cm.exception), 'TearDownModuleExc')
         self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test',
-                                    'tearDownClass'])
+                                    'tearDownClass', 'tearDownModule'])
         self.assertTrue(unittest.case._module_cleanups)
         unittest.case._module_cleanups.clear()
 
diff --git a/common/py3-stdlib/unittest/test/testmock/testasync.py b/common/py3-stdlib/unittest/test/testmock/testasync.py
index e1866a3..61269d6 100644
--- a/common/py3-stdlib/unittest/test/testmock/testasync.py
+++ b/common/py3-stdlib/unittest/test/testmock/testasync.py
@@ -8,7 +8,7 @@
 from asyncio import run, iscoroutinefunction
 from unittest import IsolatedAsyncioTestCase
 from unittest.mock import (ANY, call, AsyncMock, patch, MagicMock, Mock,
-                           create_autospec, sentinel, _CallList)
+                           create_autospec, sentinel, _CallList, seal)
 
 
 def tearDownModule():
@@ -146,6 +146,23 @@
 
         run(test_async())
 
+    def test_patch_dict_async_def(self):
+        foo = {'a': 'a'}
+        @patch.dict(foo, {'a': 'b'})
+        async def test_async():
+            self.assertEqual(foo['a'], 'b')
+
+        self.assertTrue(iscoroutinefunction(test_async))
+        run(test_async())
+
+    def test_patch_dict_async_def_context(self):
+        foo = {'a': 'a'}
+        async def test_async():
+            with patch.dict(foo, {'a': 'b'}):
+                self.assertEqual(foo['a'], 'b')
+
+        run(test_async())
+
 
 class AsyncMockTest(unittest.TestCase):
     def test_iscoroutinefunction_default(self):
@@ -281,6 +298,14 @@
         self.assertIsInstance(mock.async_method, AsyncMock)
         self.assertIsInstance(mock.normal_method, Mock)
 
+    def test_spec_normal_methods_on_class_with_mock_seal(self):
+        mock = Mock(AsyncClass)
+        seal(mock)
+        with self.assertRaises(AttributeError):
+            mock.normal_method
+        with self.assertRaises(AttributeError):
+            mock.async_method
+
     def test_spec_mock_type_kw(self):
         def inner_test(mock_type):
             async_mock = mock_type(spec=async_func)
@@ -1057,3 +1082,7 @@
                         'Actual: [call(1)]'))) as cm:
             self.mock.assert_has_awaits([call(), call(1, 2)])
         self.assertIsInstance(cm.exception.__cause__, TypeError)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/common/py3-stdlib/unittest/test/testmock/testmock.py b/common/py3-stdlib/unittest/test/testmock/testmock.py
index fdba543..535f908 100644
--- a/common/py3-stdlib/unittest/test/testmock/testmock.py
+++ b/common/py3-stdlib/unittest/test/testmock/testmock.py
@@ -1644,6 +1644,22 @@
         m.aseert_foo_call()
         m.assrt_foo_call()
 
+    # gh-100739
+    def test_mock_safe_with_spec(self):
+        class Foo(object):
+            def assert_bar(self):
+                pass
+
+            def assertSome(self):
+                pass
+
+        m = Mock(spec=Foo)
+        m.assert_bar()
+        m.assertSome()
+
+        m.assert_bar.assert_called_once()
+        m.assertSome.assert_called_once()
+
     #Issue21262
     def test_assert_not_called(self):
         m = Mock()
diff --git a/common/py3-stdlib/urllib/error.py b/common/py3-stdlib/urllib/error.py
index 8cd901f..a9cd1ec 100644
--- a/common/py3-stdlib/urllib/error.py
+++ b/common/py3-stdlib/urllib/error.py
@@ -10,7 +10,7 @@
 an application may want to handle an exception like a regular
 response.
 """
-
+import io
 import urllib.response
 
 __all__ = ['URLError', 'HTTPError', 'ContentTooShortError']
@@ -42,12 +42,9 @@
         self.hdrs = hdrs
         self.fp = fp
         self.filename = url
-        # The addinfourl classes depend on fp being a valid file
-        # object.  In some cases, the HTTPError may not have a valid
-        # file object.  If this happens, the simplest workaround is to
-        # not initialize the base classes.
-        if fp is not None:
-            self.__super_init(fp, hdrs, url, code)
+        if fp is None:
+            fp = io.BytesIO()
+        self.__super_init(fp, hdrs, url, code)
 
     def __str__(self):
         return 'HTTP Error %s: %s' % (self.code, self.msg)
diff --git a/common/py3-stdlib/urllib/parse.py b/common/py3-stdlib/urllib/parse.py
index b35997b..26ddf30 100644
--- a/common/py3-stdlib/urllib/parse.py
+++ b/common/py3-stdlib/urllib/parse.py
@@ -171,12 +171,11 @@
     def port(self):
         port = self._hostinfo[1]
         if port is not None:
-            try:
-                port = int(port, 10)
-            except ValueError:
-                message = f'Port could not be cast to integer value as {port!r}'
-                raise ValueError(message) from None
-            if not ( 0 <= port <= 65535):
+            if port.isdigit() and port.isascii():
+                port = int(port)
+            else:
+                raise ValueError(f"Port could not be cast to integer value as {port!r}")
+            if not (0 <= port <= 65535):
                 raise ValueError("Port out of range 0-65535")
         return port
 
@@ -1125,15 +1124,15 @@
 def _splitnport(host, defport=-1):
     """Split host and port, returning numeric port.
     Return given default port if no ':' found; defaults to -1.
-    Return numerical port if a valid number are found after ':'.
+    Return numerical port if a valid number is found after ':'.
     Return None if ':' but not a valid number."""
     host, delim, port = host.rpartition(':')
     if not delim:
         host = port
     elif port:
-        try:
+        if port.isdigit() and port.isascii():
             nport = int(port)
-        except ValueError:
+        else:
             nport = None
         return host, nport
     return host, defport
diff --git a/common/py3-stdlib/urllib/request.py b/common/py3-stdlib/urllib/request.py
index 34b1b0b..76fdd71 100644
--- a/common/py3-stdlib/urllib/request.py
+++ b/common/py3-stdlib/urllib/request.py
@@ -1579,8 +1579,7 @@
             headers = email.message_from_string(headers)
             return addinfourl(fp, headers, req.full_url)
         except ftplib.all_errors as exp:
-            exc = URLError('ftp error: %r' % exp)
-            raise exc.with_traceback(sys.exc_info()[2])
+            raise URLError(exp) from exp
 
     def connect_ftp(self, user, passwd, host, port, dirs, timeout):
         return ftpwrapper(user, passwd, host, port, dirs, timeout,
@@ -2492,28 +2491,34 @@
     this seems to be the standard convention.  If you need a
     different way, you can pass a proxies dictionary to the
     [Fancy]URLopener constructor.
-
     """
-    proxies = {}
     # in order to prefer lowercase variables, process environment in
     # two passes: first matches any, second pass matches lowercase only
-    for name, value in os.environ.items():
-        name = name.lower()
-        if value and name[-6:] == '_proxy':
-            proxies[name[:-6]] = value
+
+    # select only environment variables which end in (after making lowercase) _proxy
+    proxies = {}
+    environment = []
+    for name in os.environ.keys():
+        # fast screen underscore position before more expensive case-folding
+        if len(name) > 5 and name[-6] == "_" and name[-5:].lower() == "proxy":
+            value = os.environ[name]
+            proxy_name = name[:-6].lower()
+            environment.append((name, value, proxy_name))
+            if value:
+                proxies[proxy_name] = value
     # CVE-2016-1000110 - If we are running as CGI script, forget HTTP_PROXY
     # (non-all-lowercase) as it may be set from the web server by a "Proxy:"
     # header from the client
     # If "proxy" is lowercase, it will still be used thanks to the next block
     if 'REQUEST_METHOD' in os.environ:
         proxies.pop('http', None)
-    for name, value in os.environ.items():
+    for name, value, proxy_name in environment:
+        # not case-folded, checking here for lower-case env vars only
         if name[-6:] == '_proxy':
-            name = name.lower()
             if value:
-                proxies[name[:-6]] = value
+                proxies[proxy_name] = value
             else:
-                proxies.pop(name[:-6], None)
+                proxies.pop(proxy_name, None)
     return proxies
 
 def proxy_bypass_environment(host, proxies=None):
@@ -2674,22 +2679,26 @@
                 # Returned as Unicode but problems if not converted to ASCII
                 proxyServer = str(winreg.QueryValueEx(internetSettings,
                                                        'ProxyServer')[0])
-                if '=' in proxyServer:
-                    # Per-protocol settings
-                    for p in proxyServer.split(';'):
-                        protocol, address = p.split('=', 1)
-                        # See if address has a type:// prefix
-                        if not re.match('(?:[^/:]+)://', address):
-                            address = '%s://%s' % (protocol, address)
-                        proxies[protocol] = address
-                else:
-                    # Use one setting for all protocols
-                    if proxyServer[:5] == 'http:':
-                        proxies['http'] = proxyServer
-                    else:
-                        proxies['http'] = 'http://%s' % proxyServer
-                        proxies['https'] = 'https://%s' % proxyServer
-                        proxies['ftp'] = 'ftp://%s' % proxyServer
+                if '=' not in proxyServer and ';' not in proxyServer:
+                    # Use one setting for all protocols.
+                    proxyServer = 'http={0};https={0};ftp={0}'.format(proxyServer)
+                for p in proxyServer.split(';'):
+                    protocol, address = p.split('=', 1)
+                    # See if address has a type:// prefix
+                    if not re.match('(?:[^/:]+)://', address):
+                        # Add type:// prefix to address without specifying type
+                        if protocol in ('http', 'https', 'ftp'):
+                            # The default proxy type of Windows is HTTP
+                            address = 'http://' + address
+                        elif protocol == 'socks':
+                            address = 'socks://' + address
+                    proxies[protocol] = address
+                # Use SOCKS proxy for HTTP(S) protocols
+                if proxies.get('socks'):
+                    # The default SOCKS proxy type of Windows is SOCKS4
+                    address = re.sub(r'^socks://', 'socks4://', proxies['socks'])
+                    proxies['http'] = proxies.get('http') or address
+                    proxies['https'] = proxies.get('https') or address
             internetSettings.Close()
         except (OSError, ValueError, TypeError):
             # Either registry key not found etc, or the value in an
diff --git a/common/py3-stdlib/uuid.py b/common/py3-stdlib/uuid.py
index 5ae0a3e..fe9f87b 100644
--- a/common/py3-stdlib/uuid.py
+++ b/common/py3-stdlib/uuid.py
@@ -370,7 +370,12 @@
         # for are actually localized, but in theory some system could do so.)
         env = dict(os.environ)
         env['LC_ALL'] = 'C'
-        proc = subprocess.Popen((executable,) + args,
+        # Empty strings will be quoted by popen so we should just ommit it
+        if args != ('',):
+            command = (executable, *args)
+        else:
+            command = (executable,)
+        proc = subprocess.Popen(command,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.DEVNULL,
                                 env=env)
@@ -510,7 +515,7 @@
         mac = _find_mac_near_keyword('ifconfig', args, keywords, lambda i: i+1)
         if mac:
             return mac
-        return None
+    return None
 
 def _ip_getnode():
     """Get the hardware address on Unix by running ip."""
diff --git a/common/py3-stdlib/wsgiref/validate.py b/common/py3-stdlib/wsgiref/validate.py
index 6e16578..6044e32 100644
--- a/common/py3-stdlib/wsgiref/validate.py
+++ b/common/py3-stdlib/wsgiref/validate.py
@@ -1,6 +1,6 @@
 # (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org)
-# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
-# Also licenced under the Apache License, 2.0: http://opensource.org/licenses/apache2.0.php
+# Licensed under the MIT license: https://opensource.org/licenses/mit-license.php
+# Also licenced under the Apache License, 2.0: https://opensource.org/licenses/apache2.0.php
 # Licensed to PSF under a Contributor Agreement
 """
 Middleware to check for obedience to the WSGI specification.
diff --git a/common/py3-stdlib/xml/dom/minidom.py b/common/py3-stdlib/xml/dom/minidom.py
index d09ef5e..ef8a159 100644
--- a/common/py3-stdlib/xml/dom/minidom.py
+++ b/common/py3-stdlib/xml/dom/minidom.py
@@ -358,6 +358,8 @@
         self._name = qName
         self.namespaceURI = namespaceURI
         self._prefix = prefix
+        if localName is not None:
+            self._localName = localName
         self.childNodes = NodeList()
 
         # Add the single child node that represents the value of the attr
diff --git a/common/py3-stdlib/xml/etree/ElementPath.py b/common/py3-stdlib/xml/etree/ElementPath.py
index a1170b5..cd3c354 100644
--- a/common/py3-stdlib/xml/etree/ElementPath.py
+++ b/common/py3-stdlib/xml/etree/ElementPath.py
@@ -226,7 +226,6 @@
 
 def prepare_predicate(next, token):
     # FIXME: replace with real parser!!! refs:
-    # http://effbot.org/zone/simple-iterator-parser.htm
     # http://javascript.crockford.com/tdop/tdop.html
     signature = []
     predicate = []
diff --git a/common/py3-stdlib/xml/etree/ElementTree.py b/common/py3-stdlib/xml/etree/ElementTree.py
index 07be860..2503d9e 100644
--- a/common/py3-stdlib/xml/etree/ElementTree.py
+++ b/common/py3-stdlib/xml/etree/ElementTree.py
@@ -728,16 +728,11 @@
                 encoding = "utf-8"
             else:
                 encoding = "us-ascii"
-        enc_lower = encoding.lower()
-        with _get_writer(file_or_filename, enc_lower) as write:
+        with _get_writer(file_or_filename, encoding) as (write, declared_encoding):
             if method == "xml" and (xml_declaration or
                     (xml_declaration is None and
-                     enc_lower not in ("utf-8", "us-ascii", "unicode"))):
-                declared_encoding = encoding
-                if enc_lower == "unicode":
-                    # Retrieve the default encoding for the xml declaration
-                    import locale
-                    declared_encoding = locale.getpreferredencoding()
+                     encoding.lower() != "unicode" and
+                     declared_encoding.lower() not in ("utf-8", "us-ascii"))):
                 write("<?xml version='1.0' encoding='%s'?>\n" % (
                     declared_encoding,))
             if method == "text":
@@ -762,19 +757,17 @@
         write = file_or_filename.write
     except AttributeError:
         # file_or_filename is a file name
-        if encoding == "unicode":
-            file = open(file_or_filename, "w")
-        else:
-            file = open(file_or_filename, "w", encoding=encoding,
-                        errors="xmlcharrefreplace")
-        with file:
-            yield file.write
+        if encoding.lower() == "unicode":
+            encoding="utf-8"
+        with open(file_or_filename, "w", encoding=encoding,
+                  errors="xmlcharrefreplace") as file:
+            yield file.write, encoding
     else:
         # file_or_filename is a file-like object
         # encoding determines if it is a text or binary writer
-        if encoding == "unicode":
+        if encoding.lower() == "unicode":
             # use a text writer as is
-            yield write
+            yield write, getattr(file_or_filename, "encoding", None) or "utf-8"
         else:
             # wrap a binary writer with TextIOWrapper
             with contextlib.ExitStack() as stack:
@@ -805,7 +798,7 @@
                 # Keep the original file open when the TextIOWrapper is
                 # destroyed
                 stack.callback(file.detach)
-                yield file.write
+                yield file.write, encoding
 
 def _namespaces(elem, default_namespace=None):
     # identify namespaces used in this tree
diff --git a/common/py3-stdlib/zipfile.py b/common/py3-stdlib/zipfile.py
index 67cfdfb..42e11d7 100644
--- a/common/py3-stdlib/zipfile.py
+++ b/common/py3-stdlib/zipfile.py
@@ -185,6 +185,8 @@
         i = j
     if not modified:
         return extra
+    if start != len(extra):
+        buffer.append(extra[start:])
     return b''.join(buffer)
 
 def _check_zipfile(fp):
@@ -721,7 +723,9 @@
         self._lock = lock
         self._writing = writing
         self.seekable = file.seekable
-        self.tell = file.tell
+
+    def tell(self):
+        return self._pos
 
     def seek(self, offset, whence=0):
         with self._lock:
@@ -1347,6 +1351,8 @@
             print("given, inferred, offset", offset_cd, inferred, concat)
         # self.start_dir:  Position of start of central directory
         self.start_dir = offset_cd + concat
+        if self.start_dir < 0:
+            raise BadZipFile("Bad offset for central directory")
         fp.seek(self.start_dir, 0)
         data = fp.read(size_cd)
         fp = io.BytesIO(data)
@@ -2193,6 +2199,17 @@
         dir_match = name not in names and dirname in names
         return dirname if dir_match else name
 
+    def getinfo(self, name):
+        """
+        Supplement getinfo for implied dirs.
+        """
+        try:
+            return super().getinfo(name)
+        except KeyError:
+            if not name.endswith('/') or name not in self._name_set():
+                raise
+            return ZipInfo(filename=name)
+
     @classmethod
     def make(cls, source):
         """
@@ -2232,6 +2249,11 @@
         return self.__lookup
 
 
+def _extract_text_encoding(encoding=None, *args, **kwargs):
+    # stacklevel=3 so that the caller of the caller see any warning.
+    return io.text_encoding(encoding, 3), args, kwargs
+
+
 class Path:
     """
     A pathlib-compatible interface for zip files.
@@ -2341,9 +2363,9 @@
             if args or kwargs:
                 raise ValueError("encoding args invalid for binary operation")
             return stream
-        else:
-            kwargs["encoding"] = io.text_encoding(kwargs.get("encoding"))
-        return io.TextIOWrapper(stream, *args, **kwargs)
+        # Text mode:
+        encoding, args, kwargs = _extract_text_encoding(*args, **kwargs)
+        return io.TextIOWrapper(stream, encoding, *args, **kwargs)
 
     @property
     def name(self):
@@ -2354,8 +2376,8 @@
         return pathlib.Path(self.root.filename).joinpath(self.at)
 
     def read_text(self, *args, **kwargs):
-        kwargs["encoding"] = io.text_encoding(kwargs.get("encoding"))
-        with self.open('r', *args, **kwargs) as strm:
+        encoding, args, kwargs = _extract_text_encoding(*args, **kwargs)
+        with self.open('r', encoding, *args, **kwargs) as strm:
             return strm.read()
 
     def read_bytes(self):
diff --git a/common/py3-stdlib/zipimport.py b/common/py3-stdlib/zipimport.py
index 25eaee9..28e4e09 100644
--- a/common/py3-stdlib/zipimport.py
+++ b/common/py3-stdlib/zipimport.py
@@ -406,114 +406,121 @@
         raise ZipImportError(f"can't open Zip file: {archive!r}", path=archive)
 
     with fp:
+        # GH-87235: On macOS all file descriptors for /dev/fd/N share the same
+        # file offset, reset the file offset after scanning the zipfile diretory
+        # to not cause problems when some runs 'python3 /dev/fd/9 9<some_script'
+        start_offset = fp.tell()
         try:
-            fp.seek(-END_CENTRAL_DIR_SIZE, 2)
-            header_position = fp.tell()
-            buffer = fp.read(END_CENTRAL_DIR_SIZE)
-        except OSError:
-            raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive)
-        if len(buffer) != END_CENTRAL_DIR_SIZE:
-            raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive)
-        if buffer[:4] != STRING_END_ARCHIVE:
-            # Bad: End of Central Dir signature
-            # Check if there's a comment.
             try:
-                fp.seek(0, 2)
-                file_size = fp.tell()
+                fp.seek(-END_CENTRAL_DIR_SIZE, 2)
+                header_position = fp.tell()
+                buffer = fp.read(END_CENTRAL_DIR_SIZE)
             except OSError:
-                raise ZipImportError(f"can't read Zip file: {archive!r}",
-                                     path=archive)
-            max_comment_start = max(file_size - MAX_COMMENT_LEN -
-                                    END_CENTRAL_DIR_SIZE, 0)
-            try:
-                fp.seek(max_comment_start)
-                data = fp.read()
-            except OSError:
-                raise ZipImportError(f"can't read Zip file: {archive!r}",
-                                     path=archive)
-            pos = data.rfind(STRING_END_ARCHIVE)
-            if pos < 0:
-                raise ZipImportError(f'not a Zip file: {archive!r}',
-                                     path=archive)
-            buffer = data[pos:pos+END_CENTRAL_DIR_SIZE]
+                raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive)
             if len(buffer) != END_CENTRAL_DIR_SIZE:
-                raise ZipImportError(f"corrupt Zip file: {archive!r}",
-                                     path=archive)
-            header_position = file_size - len(data) + pos
-
-        header_size = _unpack_uint32(buffer[12:16])
-        header_offset = _unpack_uint32(buffer[16:20])
-        if header_position < header_size:
-            raise ZipImportError(f'bad central directory size: {archive!r}', path=archive)
-        if header_position < header_offset:
-            raise ZipImportError(f'bad central directory offset: {archive!r}', path=archive)
-        header_position -= header_size
-        arc_offset = header_position - header_offset
-        if arc_offset < 0:
-            raise ZipImportError(f'bad central directory size or offset: {archive!r}', path=archive)
-
-        files = {}
-        # Start of Central Directory
-        count = 0
-        try:
-            fp.seek(header_position)
-        except OSError:
-            raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive)
-        while True:
-            buffer = fp.read(46)
-            if len(buffer) < 4:
-                raise EOFError('EOF read where not expected')
-            # Start of file header
-            if buffer[:4] != b'PK\x01\x02':
-                break                                # Bad: Central Dir File Header
-            if len(buffer) != 46:
-                raise EOFError('EOF read where not expected')
-            flags = _unpack_uint16(buffer[8:10])
-            compress = _unpack_uint16(buffer[10:12])
-            time = _unpack_uint16(buffer[12:14])
-            date = _unpack_uint16(buffer[14:16])
-            crc = _unpack_uint32(buffer[16:20])
-            data_size = _unpack_uint32(buffer[20:24])
-            file_size = _unpack_uint32(buffer[24:28])
-            name_size = _unpack_uint16(buffer[28:30])
-            extra_size = _unpack_uint16(buffer[30:32])
-            comment_size = _unpack_uint16(buffer[32:34])
-            file_offset = _unpack_uint32(buffer[42:46])
-            header_size = name_size + extra_size + comment_size
-            if file_offset > header_offset:
-                raise ZipImportError(f'bad local header offset: {archive!r}', path=archive)
-            file_offset += arc_offset
-
-            try:
-                name = fp.read(name_size)
-            except OSError:
                 raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive)
-            if len(name) != name_size:
-                raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive)
-            # On Windows, calling fseek to skip over the fields we don't use is
-            # slower than reading the data because fseek flushes stdio's
-            # internal buffers.    See issue #8745.
-            try:
-                if len(fp.read(header_size - name_size)) != header_size - name_size:
-                    raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive)
-            except OSError:
-                raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive)
-
-            if flags & 0x800:
-                # UTF-8 file names extension
-                name = name.decode()
-            else:
-                # Historical ZIP filename encoding
+            if buffer[:4] != STRING_END_ARCHIVE:
+                # Bad: End of Central Dir signature
+                # Check if there's a comment.
                 try:
-                    name = name.decode('ascii')
-                except UnicodeDecodeError:
-                    name = name.decode('latin1').translate(cp437_table)
+                    fp.seek(0, 2)
+                    file_size = fp.tell()
+                except OSError:
+                    raise ZipImportError(f"can't read Zip file: {archive!r}",
+                                         path=archive)
+                max_comment_start = max(file_size - MAX_COMMENT_LEN -
+                                        END_CENTRAL_DIR_SIZE, 0)
+                try:
+                    fp.seek(max_comment_start)
+                    data = fp.read()
+                except OSError:
+                    raise ZipImportError(f"can't read Zip file: {archive!r}",
+                                         path=archive)
+                pos = data.rfind(STRING_END_ARCHIVE)
+                if pos < 0:
+                    raise ZipImportError(f'not a Zip file: {archive!r}',
+                                         path=archive)
+                buffer = data[pos:pos+END_CENTRAL_DIR_SIZE]
+                if len(buffer) != END_CENTRAL_DIR_SIZE:
+                    raise ZipImportError(f"corrupt Zip file: {archive!r}",
+                                         path=archive)
+                header_position = file_size - len(data) + pos
 
-            name = name.replace('/', path_sep)
-            path = _bootstrap_external._path_join(archive, name)
-            t = (path, compress, data_size, file_size, file_offset, time, date, crc)
-            files[name] = t
-            count += 1
+            header_size = _unpack_uint32(buffer[12:16])
+            header_offset = _unpack_uint32(buffer[16:20])
+            if header_position < header_size:
+                raise ZipImportError(f'bad central directory size: {archive!r}', path=archive)
+            if header_position < header_offset:
+                raise ZipImportError(f'bad central directory offset: {archive!r}', path=archive)
+            header_position -= header_size
+            arc_offset = header_position - header_offset
+            if arc_offset < 0:
+                raise ZipImportError(f'bad central directory size or offset: {archive!r}', path=archive)
+
+            files = {}
+            # Start of Central Directory
+            count = 0
+            try:
+                fp.seek(header_position)
+            except OSError:
+                raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive)
+            while True:
+                buffer = fp.read(46)
+                if len(buffer) < 4:
+                    raise EOFError('EOF read where not expected')
+                # Start of file header
+                if buffer[:4] != b'PK\x01\x02':
+                    break                                # Bad: Central Dir File Header
+                if len(buffer) != 46:
+                    raise EOFError('EOF read where not expected')
+                flags = _unpack_uint16(buffer[8:10])
+                compress = _unpack_uint16(buffer[10:12])
+                time = _unpack_uint16(buffer[12:14])
+                date = _unpack_uint16(buffer[14:16])
+                crc = _unpack_uint32(buffer[16:20])
+                data_size = _unpack_uint32(buffer[20:24])
+                file_size = _unpack_uint32(buffer[24:28])
+                name_size = _unpack_uint16(buffer[28:30])
+                extra_size = _unpack_uint16(buffer[30:32])
+                comment_size = _unpack_uint16(buffer[32:34])
+                file_offset = _unpack_uint32(buffer[42:46])
+                header_size = name_size + extra_size + comment_size
+                if file_offset > header_offset:
+                    raise ZipImportError(f'bad local header offset: {archive!r}', path=archive)
+                file_offset += arc_offset
+
+                try:
+                    name = fp.read(name_size)
+                except OSError:
+                    raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive)
+                if len(name) != name_size:
+                    raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive)
+                # On Windows, calling fseek to skip over the fields we don't use is
+                # slower than reading the data because fseek flushes stdio's
+                # internal buffers.    See issue #8745.
+                try:
+                    if len(fp.read(header_size - name_size)) != header_size - name_size:
+                        raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive)
+                except OSError:
+                    raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive)
+
+                if flags & 0x800:
+                    # UTF-8 file names extension
+                    name = name.decode()
+                else:
+                    # Historical ZIP filename encoding
+                    try:
+                        name = name.decode('ascii')
+                    except UnicodeDecodeError:
+                        name = name.decode('latin1').translate(cp437_table)
+
+                name = name.replace('/', path_sep)
+                path = _bootstrap_external._path_join(archive, name)
+                t = (path, compress, data_size, file_size, file_offset, time, date, crc)
+                files[name] = t
+                count += 1
+        finally:
+            fp.seek(start_offset)
     _bootstrap._verbose_message('zipimport: found {} names in {!r}', count, archive)
     return files
 
diff --git a/darwin-x86/bin/acp b/darwin-x86/bin/acp
index 5180e39..f12b755 100755
--- a/darwin-x86/bin/acp
+++ b/darwin-x86/bin/acp
Binary files differ
diff --git a/darwin-x86/bin/aidl b/darwin-x86/bin/aidl
index df20cdc..444c19e 100755
--- a/darwin-x86/bin/aidl
+++ b/darwin-x86/bin/aidl
Binary files differ
diff --git a/darwin-x86/bin/bison b/darwin-x86/bin/bison
index ed5251d..aa865b7 100755
--- a/darwin-x86/bin/bison
+++ b/darwin-x86/bin/bison
Binary files differ
diff --git a/darwin-x86/bin/bloaty b/darwin-x86/bin/bloaty
index f609390..5866df6 100755
--- a/darwin-x86/bin/bloaty
+++ b/darwin-x86/bin/bloaty
Binary files differ
diff --git a/darwin-x86/bin/brotli b/darwin-x86/bin/brotli
index d901cfd..082df03 100755
--- a/darwin-x86/bin/brotli
+++ b/darwin-x86/bin/brotli
Binary files differ
diff --git a/darwin-x86/bin/bzip2 b/darwin-x86/bin/bzip2
index b516f62..ccbed05 100755
--- a/darwin-x86/bin/bzip2
+++ b/darwin-x86/bin/bzip2
Binary files differ
diff --git a/darwin-x86/bin/ckati b/darwin-x86/bin/ckati
index 18d74a4..9c5416d 100755
--- a/darwin-x86/bin/ckati
+++ b/darwin-x86/bin/ckati
Binary files differ
diff --git a/darwin-x86/bin/ckati_stamp_dump b/darwin-x86/bin/ckati_stamp_dump
deleted file mode 100755
index 2a3ca09..0000000
--- a/darwin-x86/bin/ckati_stamp_dump
+++ /dev/null
Binary files differ
diff --git a/darwin-x86/bin/flex b/darwin-x86/bin/flex
index ce60ae1..f1408e3 100755
--- a/darwin-x86/bin/flex
+++ b/darwin-x86/bin/flex
Binary files differ
diff --git a/darwin-x86/bin/gavinhoward-bc b/darwin-x86/bin/gavinhoward-bc
index 0bd34be..1287023 100755
--- a/darwin-x86/bin/gavinhoward-bc
+++ b/darwin-x86/bin/gavinhoward-bc
Binary files differ
diff --git a/darwin-x86/bin/hidl-gen b/darwin-x86/bin/hidl-gen
index 98a6f67..7ce2271 100755
--- a/darwin-x86/bin/hidl-gen
+++ b/darwin-x86/bin/hidl-gen
Binary files differ
diff --git a/darwin-x86/bin/hidl-lint b/darwin-x86/bin/hidl-lint
index 5285f24..3fc2368 100755
--- a/darwin-x86/bin/hidl-lint
+++ b/darwin-x86/bin/hidl-lint
Binary files differ
diff --git a/darwin-x86/bin/m4 b/darwin-x86/bin/m4
index de9e43b..e2502a7 100755
--- a/darwin-x86/bin/m4
+++ b/darwin-x86/bin/m4
Binary files differ
diff --git a/darwin-x86/bin/make b/darwin-x86/bin/make
index 317c832..6aa2204 100755
--- a/darwin-x86/bin/make
+++ b/darwin-x86/bin/make
Binary files differ
diff --git a/darwin-x86/bin/ninja b/darwin-x86/bin/ninja
index a7289f0..19a65b4 100755
--- a/darwin-x86/bin/ninja
+++ b/darwin-x86/bin/ninja
Binary files differ
diff --git a/darwin-x86/bin/one-true-awk b/darwin-x86/bin/one-true-awk
index 0a6bdcf..2fda15d 100755
--- a/darwin-x86/bin/one-true-awk
+++ b/darwin-x86/bin/one-true-awk
Binary files differ
diff --git a/darwin-x86/bin/openssl b/darwin-x86/bin/openssl
index 3f6a706..ac65afd 100755
--- a/darwin-x86/bin/openssl
+++ b/darwin-x86/bin/openssl
Binary files differ
diff --git a/darwin-x86/bin/py3-cmd b/darwin-x86/bin/py3-cmd
index f6dedcf..e5019a5 100755
--- a/darwin-x86/bin/py3-cmd
+++ b/darwin-x86/bin/py3-cmd
Binary files differ
diff --git a/darwin-x86/bin/py3-launcher-autorun64 b/darwin-x86/bin/py3-launcher-autorun64
index c991a06..90b5703 100755
--- a/darwin-x86/bin/py3-launcher-autorun64
+++ b/darwin-x86/bin/py3-launcher-autorun64
Binary files differ
diff --git a/darwin-x86/bin/py3-launcher64 b/darwin-x86/bin/py3-launcher64
index 16f25d2..6f2206f 100755
--- a/darwin-x86/bin/py3-launcher64
+++ b/darwin-x86/bin/py3-launcher64
Binary files differ
diff --git a/darwin-x86/bin/toybox b/darwin-x86/bin/toybox
index 6ced8a7..bc43038 100755
--- a/darwin-x86/bin/toybox
+++ b/darwin-x86/bin/toybox
Binary files differ
diff --git a/darwin-x86/bin/xz b/darwin-x86/bin/xz
index cab41ae..13a2f7f 100755
--- a/darwin-x86/bin/xz
+++ b/darwin-x86/bin/xz
Binary files differ
diff --git a/darwin-x86/bin/zip2zip b/darwin-x86/bin/zip2zip
index 7e8d57c..c5a1027 100755
--- a/darwin-x86/bin/zip2zip
+++ b/darwin-x86/bin/zip2zip
Binary files differ
diff --git a/darwin-x86/bin/zipalign b/darwin-x86/bin/zipalign
index 147937a..96ee545 100755
--- a/darwin-x86/bin/zipalign
+++ b/darwin-x86/bin/zipalign
Binary files differ
diff --git a/darwin-x86/bin/ziptime b/darwin-x86/bin/ziptime
index 8e9a927..3477b1c 100755
--- a/darwin-x86/bin/ziptime
+++ b/darwin-x86/bin/ziptime
Binary files differ
diff --git a/darwin-x86/bin/ziptool b/darwin-x86/bin/ziptool
index 84f2fd5..c450df8 100755
--- a/darwin-x86/bin/ziptool
+++ b/darwin-x86/bin/ziptool
Binary files differ
diff --git a/darwin-x86/lib64/libbase.dylib b/darwin-x86/lib64/libbase.dylib
index 0ccafc9..b2775e0 100755
--- a/darwin-x86/lib64/libbase.dylib
+++ b/darwin-x86/lib64/libbase.dylib
Binary files differ
diff --git a/darwin-x86/lib64/libc++.dylib b/darwin-x86/lib64/libc++.dylib
index 6f267b3..053a942 100755
--- a/darwin-x86/lib64/libc++.dylib
+++ b/darwin-x86/lib64/libc++.dylib
Binary files differ
diff --git a/darwin-x86/lib64/libcrypto-host.dylib b/darwin-x86/lib64/libcrypto-host.dylib
index 935db43..cef5cd1 100755
--- a/darwin-x86/lib64/libcrypto-host.dylib
+++ b/darwin-x86/lib64/libcrypto-host.dylib
Binary files differ
diff --git a/darwin-x86/lib64/libicui18n-host.dylib b/darwin-x86/lib64/libicui18n-host.dylib
index 38d7949..c7af51d 100755
--- a/darwin-x86/lib64/libicui18n-host.dylib
+++ b/darwin-x86/lib64/libicui18n-host.dylib
Binary files differ
diff --git a/darwin-x86/lib64/libicuuc-host.dylib b/darwin-x86/lib64/libicuuc-host.dylib
index a451775..ad64b5f 100755
--- a/darwin-x86/lib64/libicuuc-host.dylib
+++ b/darwin-x86/lib64/libicuuc-host.dylib
Binary files differ
diff --git a/darwin-x86/lib64/liblog.dylib b/darwin-x86/lib64/liblog.dylib
index 5a4658b..83cd928 100755
--- a/darwin-x86/lib64/liblog.dylib
+++ b/darwin-x86/lib64/liblog.dylib
Binary files differ
diff --git a/darwin-x86/lib64/libsqlite.dylib b/darwin-x86/lib64/libsqlite.dylib
index ce0680e..eb4c89c 100755
--- a/darwin-x86/lib64/libsqlite.dylib
+++ b/darwin-x86/lib64/libsqlite.dylib
Binary files differ
diff --git a/darwin-x86/lib64/libz-host.dylib b/darwin-x86/lib64/libz-host.dylib
index bbd2b2d..58f21e4 100755
--- a/darwin-x86/lib64/libz-host.dylib
+++ b/darwin-x86/lib64/libz-host.dylib
Binary files differ
diff --git a/darwin-x86/lib64/libziparchive.dylib b/darwin-x86/lib64/libziparchive.dylib
index 555c2f6..8c82ff2 100755
--- a/darwin-x86/lib64/libziparchive.dylib
+++ b/darwin-x86/lib64/libziparchive.dylib
Binary files differ
diff --git a/linux-x86/asan/bin/aidl b/linux-x86/asan/bin/aidl
index fdaa4af..dc80e28 100755
--- a/linux-x86/asan/bin/aidl
+++ b/linux-x86/asan/bin/aidl
Binary files differ
diff --git a/linux-x86/asan/bin/ckati b/linux-x86/asan/bin/ckati
index 79acbd6..702c08b 100755
--- a/linux-x86/asan/bin/ckati
+++ b/linux-x86/asan/bin/ckati
Binary files differ
diff --git a/linux-x86/asan/bin/toybox b/linux-x86/asan/bin/toybox
index d10c623..06cd826 100755
--- a/linux-x86/asan/bin/toybox
+++ b/linux-x86/asan/bin/toybox
Binary files differ
diff --git a/linux-x86/asan/bin/zipalign b/linux-x86/asan/bin/zipalign
index 2cf937a..e230299 100755
--- a/linux-x86/asan/bin/zipalign
+++ b/linux-x86/asan/bin/zipalign
Binary files differ
diff --git a/linux-x86/asan/lib64/libc++.so b/linux-x86/asan/lib64/libc++.so
index 1abac9a..12a423c 100755
--- a/linux-x86/asan/lib64/libc++.so
+++ b/linux-x86/asan/lib64/libc++.so
Binary files differ
diff --git a/linux-x86/asan/lib64/libcrypto-host.so b/linux-x86/asan/lib64/libcrypto-host.so
index d9cc492..9623ee9 100755
--- a/linux-x86/asan/lib64/libcrypto-host.so
+++ b/linux-x86/asan/lib64/libcrypto-host.so
Binary files differ
diff --git a/linux-x86/asan/lib64/liblog.so b/linux-x86/asan/lib64/liblog.so
index 26abad8..46b0e48 100755
--- a/linux-x86/asan/lib64/liblog.so
+++ b/linux-x86/asan/lib64/liblog.so
Binary files differ
diff --git a/linux-x86/bin/aidl b/linux-x86/bin/aidl
index 384b5bb..c8a803c 100755
--- a/linux-x86/bin/aidl
+++ b/linux-x86/bin/aidl
Binary files differ
diff --git a/linux-x86/bin/bloaty b/linux-x86/bin/bloaty
index 4256202..9cd81bb 100755
--- a/linux-x86/bin/bloaty
+++ b/linux-x86/bin/bloaty
Binary files differ
diff --git a/linux-x86/bin/ckati b/linux-x86/bin/ckati
index d191531..2d4fcf2 100755
--- a/linux-x86/bin/ckati
+++ b/linux-x86/bin/ckati
Binary files differ
diff --git a/linux-x86/bin/ckati_stamp_dump b/linux-x86/bin/ckati_stamp_dump
deleted file mode 100755
index 51e3173..0000000
--- a/linux-x86/bin/ckati_stamp_dump
+++ /dev/null
Binary files differ
diff --git a/linux-x86/bin/create_minidebuginfo b/linux-x86/bin/create_minidebuginfo
index 95e6c76..c5144cd 100755
--- a/linux-x86/bin/create_minidebuginfo
+++ b/linux-x86/bin/create_minidebuginfo
Binary files differ
diff --git a/linux-x86/bin/hidl-gen b/linux-x86/bin/hidl-gen
index a641882..ac5e707 100755
--- a/linux-x86/bin/hidl-gen
+++ b/linux-x86/bin/hidl-gen
Binary files differ
diff --git a/linux-x86/bin/hidl-lint b/linux-x86/bin/hidl-lint
index ea8f4af..c8db2a5 100755
--- a/linux-x86/bin/hidl-lint
+++ b/linux-x86/bin/hidl-lint
Binary files differ
diff --git a/linux-x86/bin/py2-cmd b/linux-x86/bin/py2-cmd
index b5218d4..62f6f2e 100755
--- a/linux-x86/bin/py2-cmd
+++ b/linux-x86/bin/py2-cmd
Binary files differ
diff --git a/linux-x86/bin/py3-cmd b/linux-x86/bin/py3-cmd
index 42db088..8086776 100755
--- a/linux-x86/bin/py3-cmd
+++ b/linux-x86/bin/py3-cmd
Binary files differ
diff --git a/linux-x86/bin/py3-launcher-autorun64 b/linux-x86/bin/py3-launcher-autorun64
index 5ce8096..fc6242f 100755
--- a/linux-x86/bin/py3-launcher-autorun64
+++ b/linux-x86/bin/py3-launcher-autorun64
Binary files differ
diff --git a/linux-x86/bin/py3-launcher64 b/linux-x86/bin/py3-launcher64
index afd8e73..b761352 100755
--- a/linux-x86/bin/py3-launcher64
+++ b/linux-x86/bin/py3-launcher64
Binary files differ
diff --git a/linux-x86/bin/toybox b/linux-x86/bin/toybox
index 51c887c..2b89e10 100755
--- a/linux-x86/bin/toybox
+++ b/linux-x86/bin/toybox
Binary files differ
diff --git a/linux-x86/bin/zip2zip b/linux-x86/bin/zip2zip
index 824d273..407cca8 100755
--- a/linux-x86/bin/zip2zip
+++ b/linux-x86/bin/zip2zip
Binary files differ
diff --git a/linux-x86/bin/zipalign b/linux-x86/bin/zipalign
index 182f8b9..62f5ef7 100755
--- a/linux-x86/bin/zipalign
+++ b/linux-x86/bin/zipalign
Binary files differ
diff --git a/linux-x86/lib64/libc++.so b/linux-x86/lib64/libc++.so
index b36426e..c8584bb 100755
--- a/linux-x86/lib64/libc++.so
+++ b/linux-x86/lib64/libc++.so
Binary files differ
diff --git a/linux-x86/lib64/libcrypto-host.so b/linux-x86/lib64/libcrypto-host.so
index cf28d91..25b1f46 100755
--- a/linux-x86/lib64/libcrypto-host.so
+++ b/linux-x86/lib64/libcrypto-host.so
Binary files differ
diff --git a/linux-x86/lib64/libicui18n-host.so b/linux-x86/lib64/libicui18n-host.so
index ce06a5a..6ad9491 100755
--- a/linux-x86/lib64/libicui18n-host.so
+++ b/linux-x86/lib64/libicui18n-host.so
Binary files differ
diff --git a/linux-x86/lib64/liblog.so b/linux-x86/lib64/liblog.so
index 593e388..94a9411 100755
--- a/linux-x86/lib64/liblog.so
+++ b/linux-x86/lib64/liblog.so
Binary files differ
diff --git a/linux-x86/lib64/libprotobuf-cpp-full.so b/linux-x86/lib64/libprotobuf-cpp-full.so
index 65abac8..e64b3dd 100755
--- a/linux-x86/lib64/libprotobuf-cpp-full.so
+++ b/linux-x86/lib64/libprotobuf-cpp-full.so
Binary files differ
diff --git a/linux_musl-arm64/bin/aidl b/linux_musl-arm64/bin/aidl
index afc093b..2684bc1 100755
--- a/linux_musl-arm64/bin/aidl
+++ b/linux_musl-arm64/bin/aidl
Binary files differ
diff --git a/linux_musl-arm64/bin/bloaty b/linux_musl-arm64/bin/bloaty
index 8b6dffc..feb268b 100755
--- a/linux_musl-arm64/bin/bloaty
+++ b/linux_musl-arm64/bin/bloaty
Binary files differ
diff --git a/linux_musl-arm64/bin/ckati b/linux_musl-arm64/bin/ckati
index 649e578..5a1ad4d 100755
--- a/linux_musl-arm64/bin/ckati
+++ b/linux_musl-arm64/bin/ckati
Binary files differ
diff --git a/linux_musl-arm64/bin/ckati_stamp_dump b/linux_musl-arm64/bin/ckati_stamp_dump
deleted file mode 100755
index 8a247b6..0000000
--- a/linux_musl-arm64/bin/ckati_stamp_dump
+++ /dev/null
Binary files differ
diff --git a/linux_musl-arm64/bin/create_minidebuginfo b/linux_musl-arm64/bin/create_minidebuginfo
index d303c08..89d0fad 100755
--- a/linux_musl-arm64/bin/create_minidebuginfo
+++ b/linux_musl-arm64/bin/create_minidebuginfo
Binary files differ
diff --git a/linux_musl-arm64/bin/hidl-gen b/linux_musl-arm64/bin/hidl-gen
index d741ce6..f743ea8 100755
--- a/linux_musl-arm64/bin/hidl-gen
+++ b/linux_musl-arm64/bin/hidl-gen
Binary files differ
diff --git a/linux_musl-arm64/bin/hidl-lint b/linux_musl-arm64/bin/hidl-lint
index 1f1f6fb..93d3a0d 100755
--- a/linux_musl-arm64/bin/hidl-lint
+++ b/linux_musl-arm64/bin/hidl-lint
Binary files differ
diff --git a/linux_musl-arm64/bin/py2-cmd b/linux_musl-arm64/bin/py2-cmd
index 19ff72f..c6d1245 100755
--- a/linux_musl-arm64/bin/py2-cmd
+++ b/linux_musl-arm64/bin/py2-cmd
Binary files differ
diff --git a/linux_musl-arm64/bin/py3-cmd b/linux_musl-arm64/bin/py3-cmd
index 2446167..3ec68b6 100755
--- a/linux_musl-arm64/bin/py3-cmd
+++ b/linux_musl-arm64/bin/py3-cmd
Binary files differ
diff --git a/linux_musl-arm64/bin/py3-launcher-autorun-static64 b/linux_musl-arm64/bin/py3-launcher-autorun-static64
index 465f66e..e5a3a0e 100755
--- a/linux_musl-arm64/bin/py3-launcher-autorun-static64
+++ b/linux_musl-arm64/bin/py3-launcher-autorun-static64
Binary files differ
diff --git a/linux_musl-arm64/bin/py3-launcher-autorun64 b/linux_musl-arm64/bin/py3-launcher-autorun64
index 8827d71..f7208d4 100755
--- a/linux_musl-arm64/bin/py3-launcher-autorun64
+++ b/linux_musl-arm64/bin/py3-launcher-autorun64
Binary files differ
diff --git a/linux_musl-arm64/bin/py3-launcher-static64 b/linux_musl-arm64/bin/py3-launcher-static64
index 31795db..a8f4e8e 100755
--- a/linux_musl-arm64/bin/py3-launcher-static64
+++ b/linux_musl-arm64/bin/py3-launcher-static64
Binary files differ
diff --git a/linux_musl-arm64/bin/py3-launcher64 b/linux_musl-arm64/bin/py3-launcher64
index d8021ba..cfb555e 100755
--- a/linux_musl-arm64/bin/py3-launcher64
+++ b/linux_musl-arm64/bin/py3-launcher64
Binary files differ
diff --git a/linux_musl-arm64/bin/toybox b/linux_musl-arm64/bin/toybox
index 3fa7e06..dccfa76 100755
--- a/linux_musl-arm64/bin/toybox
+++ b/linux_musl-arm64/bin/toybox
Binary files differ
diff --git a/linux_musl-arm64/bin/zipalign b/linux_musl-arm64/bin/zipalign
index 57f977e..0132d4a 100755
--- a/linux_musl-arm64/bin/zipalign
+++ b/linux_musl-arm64/bin/zipalign
Binary files differ
diff --git a/linux_musl-arm64/lib64/libc++.so b/linux_musl-arm64/lib64/libc++.so
index e8e3a73..be8adf9 100755
--- a/linux_musl-arm64/lib64/libc++.so
+++ b/linux_musl-arm64/lib64/libc++.so
Binary files differ
diff --git a/linux_musl-arm64/lib64/libcrypto-host.so b/linux_musl-arm64/lib64/libcrypto-host.so
index d2dd0e9..dac56ce 100755
--- a/linux_musl-arm64/lib64/libcrypto-host.so
+++ b/linux_musl-arm64/lib64/libcrypto-host.so
Binary files differ
diff --git a/linux_musl-arm64/lib64/libicui18n-host.so b/linux_musl-arm64/lib64/libicui18n-host.so
index 213640f..3607b17 100755
--- a/linux_musl-arm64/lib64/libicui18n-host.so
+++ b/linux_musl-arm64/lib64/libicui18n-host.so
Binary files differ
diff --git a/linux_musl-arm64/lib64/liblog.so b/linux_musl-arm64/lib64/liblog.so
index 1b2b271..c5dea47 100755
--- a/linux_musl-arm64/lib64/liblog.so
+++ b/linux_musl-arm64/lib64/liblog.so
Binary files differ
diff --git a/linux_musl-arm64/lib64/libprotobuf-cpp-full.so b/linux_musl-arm64/lib64/libprotobuf-cpp-full.so
index 1e1cf92..25d64cf 100755
--- a/linux_musl-arm64/lib64/libprotobuf-cpp-full.so
+++ b/linux_musl-arm64/lib64/libprotobuf-cpp-full.so
Binary files differ
diff --git a/linux_musl-x86/asan/bin/aidl b/linux_musl-x86/asan/bin/aidl
index fdaa4af..dc80e28 100755
--- a/linux_musl-x86/asan/bin/aidl
+++ b/linux_musl-x86/asan/bin/aidl
Binary files differ
diff --git a/linux_musl-x86/asan/bin/ckati b/linux_musl-x86/asan/bin/ckati
index 79acbd6..702c08b 100755
--- a/linux_musl-x86/asan/bin/ckati
+++ b/linux_musl-x86/asan/bin/ckati
Binary files differ
diff --git a/linux_musl-x86/asan/bin/toybox b/linux_musl-x86/asan/bin/toybox
index d10c623..06cd826 100755
--- a/linux_musl-x86/asan/bin/toybox
+++ b/linux_musl-x86/asan/bin/toybox
Binary files differ
diff --git a/linux_musl-x86/asan/bin/zipalign b/linux_musl-x86/asan/bin/zipalign
index 2cf937a..e230299 100755
--- a/linux_musl-x86/asan/bin/zipalign
+++ b/linux_musl-x86/asan/bin/zipalign
Binary files differ
diff --git a/linux_musl-x86/asan/lib64/libc++.so b/linux_musl-x86/asan/lib64/libc++.so
index 1abac9a..12a423c 100755
--- a/linux_musl-x86/asan/lib64/libc++.so
+++ b/linux_musl-x86/asan/lib64/libc++.so
Binary files differ
diff --git a/linux_musl-x86/asan/lib64/libcrypto-host.so b/linux_musl-x86/asan/lib64/libcrypto-host.so
index d9cc492..9623ee9 100755
--- a/linux_musl-x86/asan/lib64/libcrypto-host.so
+++ b/linux_musl-x86/asan/lib64/libcrypto-host.so
Binary files differ
diff --git a/linux_musl-x86/asan/lib64/liblog.so b/linux_musl-x86/asan/lib64/liblog.so
index 26abad8..46b0e48 100755
--- a/linux_musl-x86/asan/lib64/liblog.so
+++ b/linux_musl-x86/asan/lib64/liblog.so
Binary files differ
diff --git a/linux_musl-x86/bin/aidl b/linux_musl-x86/bin/aidl
index 6c19161..ec350a2 100755
--- a/linux_musl-x86/bin/aidl
+++ b/linux_musl-x86/bin/aidl
Binary files differ
diff --git a/linux_musl-x86/bin/bloaty b/linux_musl-x86/bin/bloaty
index c133170..26655be 100755
--- a/linux_musl-x86/bin/bloaty
+++ b/linux_musl-x86/bin/bloaty
Binary files differ
diff --git a/linux_musl-x86/bin/ckati b/linux_musl-x86/bin/ckati
index 9f251f4..bfbe3f9 100755
--- a/linux_musl-x86/bin/ckati
+++ b/linux_musl-x86/bin/ckati
Binary files differ
diff --git a/linux_musl-x86/bin/ckati_stamp_dump b/linux_musl-x86/bin/ckati_stamp_dump
deleted file mode 100755
index 1028357..0000000
--- a/linux_musl-x86/bin/ckati_stamp_dump
+++ /dev/null
Binary files differ
diff --git a/linux_musl-x86/bin/create_minidebuginfo b/linux_musl-x86/bin/create_minidebuginfo
index 1d38ada..537f728 100755
--- a/linux_musl-x86/bin/create_minidebuginfo
+++ b/linux_musl-x86/bin/create_minidebuginfo
Binary files differ
diff --git a/linux_musl-x86/bin/hidl-gen b/linux_musl-x86/bin/hidl-gen
index 0c3c5f8..b895052 100755
--- a/linux_musl-x86/bin/hidl-gen
+++ b/linux_musl-x86/bin/hidl-gen
Binary files differ
diff --git a/linux_musl-x86/bin/hidl-lint b/linux_musl-x86/bin/hidl-lint
index b22ec89..ccad4a3 100755
--- a/linux_musl-x86/bin/hidl-lint
+++ b/linux_musl-x86/bin/hidl-lint
Binary files differ
diff --git a/linux_musl-x86/bin/py2-cmd b/linux_musl-x86/bin/py2-cmd
index 4462931..2eb4773 100755
--- a/linux_musl-x86/bin/py2-cmd
+++ b/linux_musl-x86/bin/py2-cmd
Binary files differ
diff --git a/linux_musl-x86/bin/py3-cmd b/linux_musl-x86/bin/py3-cmd
index 4613fe1..d9842c1 100755
--- a/linux_musl-x86/bin/py3-cmd
+++ b/linux_musl-x86/bin/py3-cmd
Binary files differ
diff --git a/linux_musl-x86/bin/py3-launcher-autorun-static64 b/linux_musl-x86/bin/py3-launcher-autorun-static64
index a72648e..8a1e15d 100755
--- a/linux_musl-x86/bin/py3-launcher-autorun-static64
+++ b/linux_musl-x86/bin/py3-launcher-autorun-static64
Binary files differ
diff --git a/linux_musl-x86/bin/py3-launcher-autorun64 b/linux_musl-x86/bin/py3-launcher-autorun64
index 06abfc1..c023976 100755
--- a/linux_musl-x86/bin/py3-launcher-autorun64
+++ b/linux_musl-x86/bin/py3-launcher-autorun64
Binary files differ
diff --git a/linux_musl-x86/bin/py3-launcher-static64 b/linux_musl-x86/bin/py3-launcher-static64
index 2950deb..7bd8843 100755
--- a/linux_musl-x86/bin/py3-launcher-static64
+++ b/linux_musl-x86/bin/py3-launcher-static64
Binary files differ
diff --git a/linux_musl-x86/bin/py3-launcher64 b/linux_musl-x86/bin/py3-launcher64
index 05fa323..b6c3aa9 100755
--- a/linux_musl-x86/bin/py3-launcher64
+++ b/linux_musl-x86/bin/py3-launcher64
Binary files differ
diff --git a/linux_musl-x86/bin/toybox b/linux_musl-x86/bin/toybox
index f5a51c7..4717c17 100755
--- a/linux_musl-x86/bin/toybox
+++ b/linux_musl-x86/bin/toybox
Binary files differ
diff --git a/linux_musl-x86/bin/zip2zip b/linux_musl-x86/bin/zip2zip
index 824d273..407cca8 100755
--- a/linux_musl-x86/bin/zip2zip
+++ b/linux_musl-x86/bin/zip2zip
Binary files differ
diff --git a/linux_musl-x86/bin/zipalign b/linux_musl-x86/bin/zipalign
index 04e48c9..a9e1951 100755
--- a/linux_musl-x86/bin/zipalign
+++ b/linux_musl-x86/bin/zipalign
Binary files differ
diff --git a/linux_musl-x86/lib64/libc++.so b/linux_musl-x86/lib64/libc++.so
index 629e6b1..7c55bf9 100755
--- a/linux_musl-x86/lib64/libc++.so
+++ b/linux_musl-x86/lib64/libc++.so
Binary files differ
diff --git a/linux_musl-x86/lib64/libcrypto-host.so b/linux_musl-x86/lib64/libcrypto-host.so
index b355bb5..08bdd1f 100755
--- a/linux_musl-x86/lib64/libcrypto-host.so
+++ b/linux_musl-x86/lib64/libcrypto-host.so
Binary files differ
diff --git a/linux_musl-x86/lib64/libicui18n-host.so b/linux_musl-x86/lib64/libicui18n-host.so
index bdf152a..c808493 100755
--- a/linux_musl-x86/lib64/libicui18n-host.so
+++ b/linux_musl-x86/lib64/libicui18n-host.so
Binary files differ
diff --git a/linux_musl-x86/lib64/liblog.so b/linux_musl-x86/lib64/liblog.so
index e20e1d6..765e9b1 100755
--- a/linux_musl-x86/lib64/liblog.so
+++ b/linux_musl-x86/lib64/liblog.so
Binary files differ
diff --git a/linux_musl-x86/lib64/libprotobuf-cpp-full.so b/linux_musl-x86/lib64/libprotobuf-cpp-full.so
index 9c1f1e8..65f3027 100755
--- a/linux_musl-x86/lib64/libprotobuf-cpp-full.so
+++ b/linux_musl-x86/lib64/libprotobuf-cpp-full.so
Binary files differ
diff --git a/manifest.xml b/manifest.xml
index bf3c8c7..e4f43d0 100644
--- a/manifest.xml
+++ b/manifest.xml
@@ -5,21 +5,21 @@
 
   <default revision="build-tools-release" remote="aosp" sync-j="4" />
 
-  <project path="build/make" name="platform/build" revision="2f699151d5c5571a90546e54444c08ad212e983b" upstream="build-tools-release">
+  <project path="build/make" name="platform/build" revision="cf390fa6b05cdef4e8d69849788c64c2389ec7ee" upstream="build-tools-release">
     <linkfile dest="build/tools" src="tools" />
 </project>
 
-  <project path="build/bazel" name="platform/build/bazel" groups="pdk" revision="fd861abbe9145026e2c0543e066752ad83e208e0" upstream="build-tools-release">
+  <project path="build/bazel" name="platform/build/bazel" groups="pdk" revision="4329afb5f58e1fc09f587a38a22cd4445142ef95" upstream="build-tools-release">
     <linkfile dest="WORKSPACE" src="bazel.WORKSPACE" />
 
     <linkfile dest="BUILD" src="bazel.BUILD" />
 </project>
 
-  <project path="build/bazel_common_rules" name="platform/build/bazel_common_rules" groups="pdk" revision="755c34416d03d6ccfeca2ded266d7b41bc67d391" upstream="build-tools-release" />
+  <project path="build/bazel_common_rules" name="platform/build/bazel_common_rules" groups="pdk" revision="48c5699e8332bccc8aa1fdb9f93a297daa9c2b75" upstream="build-tools-release" />
 
-  <project path="build/blueprint" name="platform/build/blueprint" revision="9486ce416768e45d66ec2a6607ea1e6968490f18" upstream="build-tools-release" />
+  <project path="build/blueprint" name="platform/build/blueprint" revision="a9f9b22d2694ecb3b6e892c8abbdfa0467bdfafa" upstream="build-tools-release" />
 
-  <project path="build/soong" name="platform/build/soong" revision="d08304b7ebd6f53c406cd03aaeebf3fe386bad56" upstream="build-tools-release">
+  <project path="build/soong" name="platform/build/soong" revision="305200dfd1957444494201ffaa183fd20ff190dc" upstream="build-tools-release">
     <linkfile dest="Android.bp" src="root.bp" />
 
     <linkfile dest="bootstrap.bash" src="bootstrap.bash" />
@@ -29,25 +29,25 @@
 
   <project path="external/golang-protobuf" name="platform/external/golang-protobuf" revision="eedb94fe4b150bb423a983671d97ddc56bdb3f7f" upstream="build-tools-release" />
 
-  <project path="packages/modules/common" name="platform/packages/modules/common" groups="pdk-cw-fs,pdk-fs" revision="fd8eb9be8f84af2e659d7bd4267398263bded26f" upstream="build-tools-release" />
+  <project path="packages/modules/common" name="platform/packages/modules/common" groups="pdk-cw-fs,pdk-fs" revision="ae35c66286e612b1cfa1d18e141eca5020c9fdbc" upstream="build-tools-release" />
 
-  <project path="prebuilts/bazel/common" name="platform/prebuilts/bazel/common" groups="pdk" clone-depth="1" revision="51aa78572d93be1bca85ee4d710b6f745c386145" upstream="build-tools-release" />
+  <project path="prebuilts/bazel/common" name="platform/prebuilts/bazel/common" groups="pdk" clone-depth="1" revision="fc16cff05c11dafbd77d2b3639117ea59172f7e8" upstream="build-tools-release" />
 
-  <project path="prebuilts/bazel/darwin-x86_64" name="platform/prebuilts/bazel/darwin-x86_64" groups="notdefault,platform-darwin,pdk" clone-depth="1" revision="60fe8421b0ba4f924c8a9f113dd800f2b1081907" upstream="build-tools-release" />
+  <project path="prebuilts/bazel/darwin-x86_64" name="platform/prebuilts/bazel/darwin-x86_64" groups="notdefault,platform-darwin,pdk" clone-depth="1" revision="0b8b012a1c261a3568604e764c109fd9d98a82a7" upstream="build-tools-release" />
 
-  <project path="prebuilts/bazel/linux-x86_64" name="platform/prebuilts/bazel/linux-x86_64" groups="linux,pdk" clone-depth="1" revision="951bd90aeabf9e4745a32ae2f36fdf1828d9d0a6" upstream="build-tools-release" />
+  <project path="prebuilts/bazel/linux-x86_64" name="platform/prebuilts/bazel/linux-x86_64" groups="linux,pdk" clone-depth="1" revision="fa0de46c3a9072eb9bd23a1f0a2c452f1ddac6fc" upstream="build-tools-release" />
 
-  <project path="prebuilts/build-tools" name="platform/prebuilts/build-tools" clone-depth="1" revision="a922daecf6e415680d14117856c522627229a5b5" upstream="build-tools-release" />
+  <project path="prebuilts/build-tools" name="platform/prebuilts/build-tools" clone-depth="1" revision="cfc1ca5bbcbc1ee62ac9adaac4564880b51e8cb9" upstream="build-tools-release" />
 
-  <project path="prebuilts/remoteexecution-client" name="platform/prebuilts/remoteexecution-client" groups="pdk" clone-depth="1" revision="932c43cd6c51d42da50a762bdeef85c73e9b804d" upstream="build-tools-release" />
+  <project path="prebuilts/remoteexecution-client" name="platform/prebuilts/remoteexecution-client" groups="pdk" clone-depth="1" revision="4df2002ef2a711d143290f54b995c719805d702b" upstream="build-tools-release" />
 
-  <project path="prebuilts/clang/host/linux-x86" name="platform/prebuilts/clang/host/linux-x86" groups="linux" clone-depth="1" revision="c72a0013ce0cff3ffe7127b7f548e74be54d1c7e" upstream="build-tools-release" />
+  <project path="prebuilts/clang/host/linux-x86" name="platform/prebuilts/clang/host/linux-x86" groups="linux" clone-depth="1" revision="0b262dcb23ece24587651248b8aa7fbb879f00ff" upstream="build-tools-release" />
 
   <project path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8" clone-depth="1" revision="f659152fc948d50e8b2c7a5b1f1dd165e6a0c8d1" upstream="build-tools-release" />
 
   <project path="prebuilts/go/linux-x86" name="platform/prebuilts/go/linux-x86" groups="linux" clone-depth="1" revision="db8dd125ecc777ce51e971d9b3dc6ab2f2c1a869" upstream="build-tools-release" />
 
-  <project path="prebuilts/clang/host/darwin-x86" name="platform/prebuilts/clang/host/darwin-x86" groups="notdefault,platform-darwin" clone-depth="1" revision="638a05f54dd23966680329e8f5b473ed087600fb" upstream="build-tools-release" />
+  <project path="prebuilts/clang/host/darwin-x86" name="platform/prebuilts/clang/host/darwin-x86" groups="notdefault,platform-darwin" clone-depth="1" revision="267b10e41170049045c28aef1cfd26ad3f754542" upstream="build-tools-release" />
 
   <project path="prebuilts/go/darwin-x86" name="platform/prebuilts/go/darwin-x86" groups="notdefault,platform-darwin" clone-depth="1" revision="f01e2c06ee0acd83183a58b0a9c24ea5b5d53ee9" upstream="build-tools-release" />
 
@@ -63,23 +63,23 @@
 
   <project path="prebuilts/clang-tools" name="platform/prebuilts/clang-tools" clone-depth="1" revision="57115430e1bab5d8174b2c53edbc9f7b7aab77e2" upstream="build-tools-release" />
 
-  <project path="prebuilts/misc" name="platform/prebuilts/misc" clone-depth="1" revision="ec2862918ae170ad723da8aaaf04a83e1dc50de4" upstream="build-tools-release" />
+  <project path="prebuilts/misc" name="platform/prebuilts/misc" clone-depth="1" revision="0c5c54b0d6e477118cd376363588e1c261ffa6c4" upstream="build-tools-release" />
 
   <project path="prebuilts/tools" name="platform/prebuilts/tools" groups="pdk,tools" clone-depth="1" revision="ba14f51bcf6d43003d2f50aa4162f7c74e92c6c8" upstream="build-tools-release" />
 
-  <project path="bionic" name="platform/bionic" revision="0dc441d41bc1c923a7bcbd722cf07e434b6e998b" upstream="build-tools-release" />
+  <project path="bionic" name="platform/bionic" revision="62ca9db49915a0e71c67b8f9bcd8376a2bad1588" upstream="build-tools-release" />
 
-  <project path="development" name="platform/development" revision="7997425658f540d0521892e923e010212529135e" upstream="build-tools-release" />
+  <project path="development" name="platform/development" revision="a9d1daf9f337827b50c0d18e1d67863c1a69995a" upstream="build-tools-release" />
 
   <project path="external/arm-optimized-routines" name="platform/external/arm-optimized-routines" revision="c5ecafecbaf8d61083d2b1b6c8732e7ea7edbead" upstream="build-tools-release" />
 
   <project path="external/auto" name="platform/external/auto" revision="addb7892c0b46e64ac5839e40625a90459b0e91e" upstream="build-tools-release" />
 
-  <project path="external/abseil-cpp" name="platform/external/abseil-cpp" revision="8c8ff494376f6836bf02bd11042f6bd528949219" upstream="build-tools-release" />
+  <project path="external/abseil-cpp" name="platform/external/abseil-cpp" revision="5a2ca3ba783b2bc5264384c21cc8554936079a36" upstream="build-tools-release" />
 
   <project path="external/bazelbuild-rules_license" name="platform/external/bazelbuild-rules_license" revision="47f082384a092ad57f0ca3c336d32812b59344aa" upstream="build-tools-release" />
 
-  <project path="external/boringssl" name="platform/external/boringssl" revision="533c5b5c735dd5267374af74b4741d3be9ea14e3" upstream="build-tools-release" />
+  <project path="external/boringssl" name="platform/external/boringssl" revision="a61a6482fe5098495978cc769b2df89a2b928bea" upstream="build-tools-release" />
 
   <project path="external/brotli" name="platform/external/brotli" revision="29dc1059970cafc136f22eb8e1f6c2ddaf0fc7dc" upstream="build-tools-release" />
 
@@ -89,7 +89,7 @@
 
   <project path="external/compiler-rt" name="platform/external/compiler-rt" revision="5eddc8d93abae4238bbd28591b9d8ff0e651932e" upstream="build-tools-release" />
 
-  <project path="external/dagger2" name="platform/external/dagger2" revision="1e8915c4cc912eb87eb6b9c9139d0eaecfbc380e" upstream="build-tools-release" />
+  <project path="external/dagger2" name="platform/external/dagger2" revision="cb2615aaf5cc09e5992372f0fbb5034a9270b608" upstream="build-tools-release" />
 
   <project path="external/error_prone" name="platform/external/error_prone" clone-depth="1" revision="6b55058ec96338a3545e1a739ac6691c80f5f405" upstream="build-tools-release" />
 
@@ -119,11 +119,11 @@
 
   <project path="external/googletest" name="platform/external/googletest" revision="b090cb66fd4fb9235a295c7d2f9e58e636851fbe" upstream="build-tools-release" />
 
-  <project path="external/guava" name="platform/external/guava" revision="fdba7437fc73bad59e729246d6a42df9eb9d76b5" upstream="build-tools-release" />
+  <project path="external/guava" name="platform/external/guava" revision="8e512d45319d87bec2220575312343c09b4b7d02" upstream="build-tools-release" />
 
   <project path="external/gson" name="platform/external/gson" groups="pdk" revision="c2e62b6b7c752d18090585ad7d2021c9dc862f8b" upstream="build-tools-release" />
 
-  <project path="external/icu" name="platform/external/icu" revision="58c13896832be62cbcd7a4d5aade172cc2476562" upstream="build-tools-release" />
+  <project path="external/icu" name="platform/external/icu" revision="60e92ae3c197b389188fd6894ecdaad13086d051" upstream="build-tools-release" />
 
   <project path="external/javapoet" name="platform/external/javapoet" revision="5556c020cb2d6c62b36abf4b3087a8765320b26a" upstream="build-tools-release" />
 
@@ -161,7 +161,7 @@
 
   <project path="external/pcre" name="platform/external/pcre" revision="14ca9f0ba43fcc8abd2bbbaf75dd19176f027614" upstream="build-tools-release" />
 
-  <project path="external/protobuf" name="platform/external/protobuf" revision="39a6278d62556729ee643b620bb28d058132c06b" upstream="build-tools-release" />
+  <project path="external/protobuf" name="platform/external/protobuf" revision="e081950acd878732dd8b3b5dee61c1f61b531660" upstream="build-tools-release" />
 
   <project path="external/safe-iop" name="platform/external/safe-iop" revision="b805514f31a231a0e78a18f296c0454fcadead1a" upstream="build-tools-release" />
 
@@ -171,7 +171,7 @@
 
   <project path="external/sqlite" name="platform/external/sqlite" revision="b46be688ed9b0cb40395dce24f97c04c18640b46" upstream="build-tools-release" />
 
-  <project path="external/starlark-go" name="platform/external/starlark-go" revision="d2295c7d1097861c7ac8b8c678506299d0b2a7d8" upstream="build-tools-release" />
+  <project path="external/starlark-go" name="platform/external/starlark-go" revision="367e1306a55919eb438568db397f5cd6aad3803e" upstream="build-tools-release" />
 
   <project path="external/tinyxml2" name="platform/external/tinyxml2" revision="54e4a18bdf47da15787bb1490d4494a75dbd3fb4" upstream="build-tools-release" />
 
@@ -179,27 +179,27 @@
 
   <project path="external/zopfli" name="platform/external/zopfli" revision="553c25fd956818afbae5e5f90ce2ddaa8863293a" upstream="build-tools-release" />
 
-  <project path="system/core" name="platform/system/core" revision="e4a9cdb97f1c987025c597455833f4144a9ebf32" upstream="build-tools-release" />
+  <project path="system/core" name="platform/system/core" revision="ff72161e4ce00f202c8b972c9e54b84e69173dc7" upstream="build-tools-release" />
 
-  <project path="system/libbase" name="platform/system/libbase" revision="bba57940eed4dfe40c77fabbf4da6a316526e99a" upstream="build-tools-release" />
+  <project path="system/libbase" name="platform/system/libbase" revision="190e75f1e65badbe15283f09827ba5adb8366695" upstream="build-tools-release" />
 
   <project path="system/libhwbinder" name="platform/system/libhwbinder" revision="3e8235e6431614c92afa5a1066dae456c587ea11" upstream="build-tools-release" />
 
   <project path="system/libziparchive" name="platform/system/libziparchive" revision="34eb8d6f43f48469a9c69be1557c105263f7bd87" upstream="build-tools-release" />
 
-  <project path="system/logging" name="platform/system/logging" revision="b258cde2966f3cd3fd3cf1dd6416612b8aa6b59f" upstream="build-tools-release" />
+  <project path="system/logging" name="platform/system/logging" revision="38bf3b1f5345dfa07b1d317e7c57e827dd04e4b1" upstream="build-tools-release" />
 
-  <project path="system/unwinding" name="platform/system/unwinding" revision="d6433e6c2fd95fdb21a6fca8907504d7fa3f94de" upstream="build-tools-release" />
+  <project path="system/unwinding" name="platform/system/unwinding" revision="dccfc4da5edce9ae90cb69a158ecc615cb6f1026" upstream="build-tools-release" />
 
   <project path="system/tools/xsdc" name="platform/system/tools/xsdc" revision="26020086ce63d61912b5b5a0da0c301e33039b5b" upstream="build-tools-release" />
 
   <project path="test/app_compat/csuite" name="platform/test/app_compat/csuite" revision="71a96ad89b89536f1d9b2066f09b22cac567e82b" upstream="build-tools-release" />
 
-  <project path="system/apex" name="platform/system/apex" groups="pdk" revision="68bb96661f443690223fbff1c7557b2028e14284" upstream="build-tools-release" />
+  <project path="system/apex" name="platform/system/apex" groups="pdk" revision="1b55e4e9871cd7fddd6912edd392732e9681ea5d" upstream="build-tools-release" />
 
-  <project path="art" name="platform/art" revision="effba2caf0c2d55c2890130600da1edd237dd0d7" upstream="build-tools-release" />
+  <project path="art" name="platform/art" revision="5d946bbecbad020f6b3bbda9a3255da982a2b090" upstream="build-tools-release" />
 
-  <project path="build/kati" name="platform/build/kati" revision="97a86efe130f4221e7329ec12856c6dea4ae3f1b" upstream="build-tools-release" />
+  <project path="build/kati" name="platform/build/kati" revision="8863034cfb657b02b76889ef3e9470ff34c31af1" upstream="build-tools-release" />
 
   <project path="dalvik" name="platform/dalvik" revision="d2833685643f946c7c188b2b22056549018112f2" upstream="build-tools-release" />
 
@@ -229,15 +229,15 @@
 
   <project path="external/python/cpython2" name="platform/external/python/cpython2" revision="0cebe3b6c590c3b55798df694a4b7f67dbb88e9f" upstream="build-tools-release" />
 
-  <project path="external/python/cpython3" name="platform/external/python/cpython3" revision="535ce70a71d97ab064c1afba978b53710ef19d44" upstream="build-tools-release" />
+  <project path="external/python/cpython3" name="platform/external/python/cpython3" revision="30e4246e28203a58b7ce381db0ed3b2c7bff58cd" upstream="build-tools-release" />
 
-  <project path="external/toybox" name="platform/external/toybox" revision="0b851a8fe455c721a64076c774231a89d2113f1b" upstream="build-tools-release" />
+  <project path="external/toybox" name="platform/external/toybox" revision="39ccd2594dd72084f2f4a71950e6bf79324f606e" upstream="build-tools-release" />
 
   <project path="external/turbine" name="platform/external/turbine" revision="b9f7152a81bc9f7fe5a9974cbe40e033828a1a58" upstream="build-tools-release" />
 
-  <project path="system/tools/aidl" name="platform/system/tools/aidl" revision="02de12c2ae5d49e235d7f03a990e745818622eda" upstream="build-tools-release" />
+  <project path="system/tools/aidl" name="platform/system/tools/aidl" revision="7a0446d3b1f21d368cff41ef6ec0d5243395349d" upstream="build-tools-release" />
 
-  <project path="system/tools/hidl" name="platform/system/tools/hidl" revision="a80b7a98c2cd8e04272dd0d2db9d3ebfe9a14f65" upstream="build-tools-release" />
+  <project path="system/tools/hidl" name="platform/system/tools/hidl" revision="c9f62f892661f3a4fdb704a2cf2eef5918ad7bcb" upstream="build-tools-release" />
 
   <project name="toolchain/go" revision="78ed6f54036fc08c477ab7f0c588fd333dc392e8" upstream="build-tools-release" />
 
diff --git a/sysroots/aarch64-unknown-linux-musl/lib/crt1.o b/sysroots/aarch64-unknown-linux-musl/lib/crt1.o
index db52857..d24f331 100644
--- a/sysroots/aarch64-unknown-linux-musl/lib/crt1.o
+++ b/sysroots/aarch64-unknown-linux-musl/lib/crt1.o
Binary files differ
diff --git a/sysroots/aarch64-unknown-linux-musl/lib/crtbegin.o b/sysroots/aarch64-unknown-linux-musl/lib/crtbegin.o
index 699adde..0e0f877 100755
--- a/sysroots/aarch64-unknown-linux-musl/lib/crtbegin.o
+++ b/sysroots/aarch64-unknown-linux-musl/lib/crtbegin.o
Binary files differ
diff --git a/sysroots/aarch64-unknown-linux-musl/lib/crtbeginS.o b/sysroots/aarch64-unknown-linux-musl/lib/crtbeginS.o
index 699adde..0e0f877 100755
--- a/sysroots/aarch64-unknown-linux-musl/lib/crtbeginS.o
+++ b/sysroots/aarch64-unknown-linux-musl/lib/crtbeginS.o
Binary files differ
diff --git a/sysroots/aarch64-unknown-linux-musl/lib/crtbeginT.o b/sysroots/aarch64-unknown-linux-musl/lib/crtbeginT.o
index 699adde..0e0f877 100755
--- a/sysroots/aarch64-unknown-linux-musl/lib/crtbeginT.o
+++ b/sysroots/aarch64-unknown-linux-musl/lib/crtbeginT.o
Binary files differ
diff --git a/sysroots/aarch64-unknown-linux-musl/lib/crtend.o b/sysroots/aarch64-unknown-linux-musl/lib/crtend.o
index 174f93a..db9e59d 100755
--- a/sysroots/aarch64-unknown-linux-musl/lib/crtend.o
+++ b/sysroots/aarch64-unknown-linux-musl/lib/crtend.o
Binary files differ
diff --git a/sysroots/aarch64-unknown-linux-musl/lib/crtendS.o b/sysroots/aarch64-unknown-linux-musl/lib/crtendS.o
index 174f93a..db9e59d 100755
--- a/sysroots/aarch64-unknown-linux-musl/lib/crtendS.o
+++ b/sysroots/aarch64-unknown-linux-musl/lib/crtendS.o
Binary files differ
diff --git a/sysroots/aarch64-unknown-linux-musl/lib/crti.o b/sysroots/aarch64-unknown-linux-musl/lib/crti.o
index 3a36ca5..03f22be 100644
--- a/sysroots/aarch64-unknown-linux-musl/lib/crti.o
+++ b/sysroots/aarch64-unknown-linux-musl/lib/crti.o
Binary files differ
diff --git a/sysroots/aarch64-unknown-linux-musl/lib/crtn.o b/sysroots/aarch64-unknown-linux-musl/lib/crtn.o
index 53c8ef1..d1ce862 100644
--- a/sysroots/aarch64-unknown-linux-musl/lib/crtn.o
+++ b/sysroots/aarch64-unknown-linux-musl/lib/crtn.o
Binary files differ
diff --git a/sysroots/aarch64-unknown-linux-musl/lib/libc++.a b/sysroots/aarch64-unknown-linux-musl/lib/libc++.a
index 2a74b92..75e489e 100644
--- a/sysroots/aarch64-unknown-linux-musl/lib/libc++.a
+++ b/sysroots/aarch64-unknown-linux-musl/lib/libc++.a
Binary files differ
diff --git a/sysroots/aarch64-unknown-linux-musl/lib/libc++.so b/sysroots/aarch64-unknown-linux-musl/lib/libc++.so
index e8e3a73..be8adf9 100755
--- a/sysroots/aarch64-unknown-linux-musl/lib/libc++.so
+++ b/sysroots/aarch64-unknown-linux-musl/lib/libc++.so
Binary files differ
diff --git a/sysroots/aarch64-unknown-linux-musl/lib/libc++abi.a b/sysroots/aarch64-unknown-linux-musl/lib/libc++abi.a
index 6deba85..131228a 100644
--- a/sysroots/aarch64-unknown-linux-musl/lib/libc++abi.a
+++ b/sysroots/aarch64-unknown-linux-musl/lib/libc++abi.a
Binary files differ
diff --git a/sysroots/aarch64-unknown-linux-musl/lib/libc.a b/sysroots/aarch64-unknown-linux-musl/lib/libc.a
index b8c2446..b8169d7 100644
--- a/sysroots/aarch64-unknown-linux-musl/lib/libc.a
+++ b/sysroots/aarch64-unknown-linux-musl/lib/libc.a
Binary files differ
diff --git a/sysroots/aarch64-unknown-linux-musl/lib/libc_musl_linker_object.o b/sysroots/aarch64-unknown-linux-musl/lib/libc_musl_linker_object.o
index 27e8ebd..5002d00 100644
--- a/sysroots/aarch64-unknown-linux-musl/lib/libc_musl_linker_object.o
+++ b/sysroots/aarch64-unknown-linux-musl/lib/libc_musl_linker_object.o
Binary files differ
diff --git a/sysroots/aarch64-unknown-linux-musl/lib/libz.a b/sysroots/aarch64-unknown-linux-musl/lib/libz.a
index 3a66ff2..7d5d7a8 100644
--- a/sysroots/aarch64-unknown-linux-musl/lib/libz.a
+++ b/sysroots/aarch64-unknown-linux-musl/lib/libz.a
Binary files differ
diff --git a/sysroots/aarch64-unknown-linux-musl/lib/rcrt1.o b/sysroots/aarch64-unknown-linux-musl/lib/rcrt1.o
index 9a991d6..608e228 100644
--- a/sysroots/aarch64-unknown-linux-musl/lib/rcrt1.o
+++ b/sysroots/aarch64-unknown-linux-musl/lib/rcrt1.o
Binary files differ
diff --git a/sysroots/arm-unknown-linux-musleabihf/lib/crt1.o b/sysroots/arm-unknown-linux-musleabihf/lib/crt1.o
index 32e3070..3d5ede8 100644
--- a/sysroots/arm-unknown-linux-musleabihf/lib/crt1.o
+++ b/sysroots/arm-unknown-linux-musleabihf/lib/crt1.o
Binary files differ
diff --git a/sysroots/arm-unknown-linux-musleabihf/lib/crtbegin.o b/sysroots/arm-unknown-linux-musleabihf/lib/crtbegin.o
index 8fd1e29..b760e3c 100755
--- a/sysroots/arm-unknown-linux-musleabihf/lib/crtbegin.o
+++ b/sysroots/arm-unknown-linux-musleabihf/lib/crtbegin.o
Binary files differ
diff --git a/sysroots/arm-unknown-linux-musleabihf/lib/crtbeginS.o b/sysroots/arm-unknown-linux-musleabihf/lib/crtbeginS.o
index 8fd1e29..b760e3c 100755
--- a/sysroots/arm-unknown-linux-musleabihf/lib/crtbeginS.o
+++ b/sysroots/arm-unknown-linux-musleabihf/lib/crtbeginS.o
Binary files differ
diff --git a/sysroots/arm-unknown-linux-musleabihf/lib/crtbeginT.o b/sysroots/arm-unknown-linux-musleabihf/lib/crtbeginT.o
index 8fd1e29..b760e3c 100755
--- a/sysroots/arm-unknown-linux-musleabihf/lib/crtbeginT.o
+++ b/sysroots/arm-unknown-linux-musleabihf/lib/crtbeginT.o
Binary files differ
diff --git a/sysroots/arm-unknown-linux-musleabihf/lib/crtend.o b/sysroots/arm-unknown-linux-musleabihf/lib/crtend.o
index 8ea3e84..4833ed2 100755
--- a/sysroots/arm-unknown-linux-musleabihf/lib/crtend.o
+++ b/sysroots/arm-unknown-linux-musleabihf/lib/crtend.o
Binary files differ
diff --git a/sysroots/arm-unknown-linux-musleabihf/lib/crtendS.o b/sysroots/arm-unknown-linux-musleabihf/lib/crtendS.o
index 8ea3e84..4833ed2 100755
--- a/sysroots/arm-unknown-linux-musleabihf/lib/crtendS.o
+++ b/sysroots/arm-unknown-linux-musleabihf/lib/crtendS.o
Binary files differ
diff --git a/sysroots/arm-unknown-linux-musleabihf/lib/crti.o b/sysroots/arm-unknown-linux-musleabihf/lib/crti.o
index 133cc7f..cfa2c86 100644
--- a/sysroots/arm-unknown-linux-musleabihf/lib/crti.o
+++ b/sysroots/arm-unknown-linux-musleabihf/lib/crti.o
Binary files differ
diff --git a/sysroots/arm-unknown-linux-musleabihf/lib/crtn.o b/sysroots/arm-unknown-linux-musleabihf/lib/crtn.o
index 58a628b..6733c9f 100644
--- a/sysroots/arm-unknown-linux-musleabihf/lib/crtn.o
+++ b/sysroots/arm-unknown-linux-musleabihf/lib/crtn.o
Binary files differ
diff --git a/sysroots/arm-unknown-linux-musleabihf/lib/libc++.a b/sysroots/arm-unknown-linux-musleabihf/lib/libc++.a
index 8aecc8f..4101b44 100644
--- a/sysroots/arm-unknown-linux-musleabihf/lib/libc++.a
+++ b/sysroots/arm-unknown-linux-musleabihf/lib/libc++.a
Binary files differ
diff --git a/sysroots/arm-unknown-linux-musleabihf/lib/libc++.so b/sysroots/arm-unknown-linux-musleabihf/lib/libc++.so
index cd64906..396b3e0 100755
--- a/sysroots/arm-unknown-linux-musleabihf/lib/libc++.so
+++ b/sysroots/arm-unknown-linux-musleabihf/lib/libc++.so
Binary files differ
diff --git a/sysroots/arm-unknown-linux-musleabihf/lib/libc++abi.a b/sysroots/arm-unknown-linux-musleabihf/lib/libc++abi.a
index 91fbec1..3f99e27 100644
--- a/sysroots/arm-unknown-linux-musleabihf/lib/libc++abi.a
+++ b/sysroots/arm-unknown-linux-musleabihf/lib/libc++abi.a
Binary files differ
diff --git a/sysroots/arm-unknown-linux-musleabihf/lib/libc.a b/sysroots/arm-unknown-linux-musleabihf/lib/libc.a
index f7c3d2b..8e6cce1 100644
--- a/sysroots/arm-unknown-linux-musleabihf/lib/libc.a
+++ b/sysroots/arm-unknown-linux-musleabihf/lib/libc.a
Binary files differ
diff --git a/sysroots/arm-unknown-linux-musleabihf/lib/libc_musl_linker_object.o b/sysroots/arm-unknown-linux-musleabihf/lib/libc_musl_linker_object.o
index 3cf5765..73ee29a 100644
--- a/sysroots/arm-unknown-linux-musleabihf/lib/libc_musl_linker_object.o
+++ b/sysroots/arm-unknown-linux-musleabihf/lib/libc_musl_linker_object.o
Binary files differ
diff --git a/sysroots/arm-unknown-linux-musleabihf/lib/libz.a b/sysroots/arm-unknown-linux-musleabihf/lib/libz.a
index 42f4c38..cc05a7a 100644
--- a/sysroots/arm-unknown-linux-musleabihf/lib/libz.a
+++ b/sysroots/arm-unknown-linux-musleabihf/lib/libz.a
Binary files differ
diff --git a/sysroots/arm-unknown-linux-musleabihf/lib/rcrt1.o b/sysroots/arm-unknown-linux-musleabihf/lib/rcrt1.o
index 4a750de..52f3a2f 100644
--- a/sysroots/arm-unknown-linux-musleabihf/lib/rcrt1.o
+++ b/sysroots/arm-unknown-linux-musleabihf/lib/rcrt1.o
Binary files differ
diff --git a/sysroots/i686-unknown-linux-musl/lib/crt1.o b/sysroots/i686-unknown-linux-musl/lib/crt1.o
index dda5f1c..82c3429 100644
--- a/sysroots/i686-unknown-linux-musl/lib/crt1.o
+++ b/sysroots/i686-unknown-linux-musl/lib/crt1.o
Binary files differ
diff --git a/sysroots/i686-unknown-linux-musl/lib/crtbegin.o b/sysroots/i686-unknown-linux-musl/lib/crtbegin.o
index 8dbd352..fd9cc9a 100755
--- a/sysroots/i686-unknown-linux-musl/lib/crtbegin.o
+++ b/sysroots/i686-unknown-linux-musl/lib/crtbegin.o
Binary files differ
diff --git a/sysroots/i686-unknown-linux-musl/lib/crtbeginS.o b/sysroots/i686-unknown-linux-musl/lib/crtbeginS.o
index 8dbd352..fd9cc9a 100755
--- a/sysroots/i686-unknown-linux-musl/lib/crtbeginS.o
+++ b/sysroots/i686-unknown-linux-musl/lib/crtbeginS.o
Binary files differ
diff --git a/sysroots/i686-unknown-linux-musl/lib/crtbeginT.o b/sysroots/i686-unknown-linux-musl/lib/crtbeginT.o
index 8dbd352..fd9cc9a 100755
--- a/sysroots/i686-unknown-linux-musl/lib/crtbeginT.o
+++ b/sysroots/i686-unknown-linux-musl/lib/crtbeginT.o
Binary files differ
diff --git a/sysroots/i686-unknown-linux-musl/lib/crtend.o b/sysroots/i686-unknown-linux-musl/lib/crtend.o
index b52f4be..e1db928 100755
--- a/sysroots/i686-unknown-linux-musl/lib/crtend.o
+++ b/sysroots/i686-unknown-linux-musl/lib/crtend.o
Binary files differ
diff --git a/sysroots/i686-unknown-linux-musl/lib/crtendS.o b/sysroots/i686-unknown-linux-musl/lib/crtendS.o
index b52f4be..e1db928 100755
--- a/sysroots/i686-unknown-linux-musl/lib/crtendS.o
+++ b/sysroots/i686-unknown-linux-musl/lib/crtendS.o
Binary files differ
diff --git a/sysroots/i686-unknown-linux-musl/lib/crti.o b/sysroots/i686-unknown-linux-musl/lib/crti.o
index 6af7322..e0c457a 100644
--- a/sysroots/i686-unknown-linux-musl/lib/crti.o
+++ b/sysroots/i686-unknown-linux-musl/lib/crti.o
Binary files differ
diff --git a/sysroots/i686-unknown-linux-musl/lib/crtn.o b/sysroots/i686-unknown-linux-musl/lib/crtn.o
index 8caede4..059d935 100644
--- a/sysroots/i686-unknown-linux-musl/lib/crtn.o
+++ b/sysroots/i686-unknown-linux-musl/lib/crtn.o
Binary files differ
diff --git a/sysroots/i686-unknown-linux-musl/lib/libc++.a b/sysroots/i686-unknown-linux-musl/lib/libc++.a
index f08fac5..51ba56c 100644
--- a/sysroots/i686-unknown-linux-musl/lib/libc++.a
+++ b/sysroots/i686-unknown-linux-musl/lib/libc++.a
Binary files differ
diff --git a/sysroots/i686-unknown-linux-musl/lib/libc++.so b/sysroots/i686-unknown-linux-musl/lib/libc++.so
index 0d7ba4a..f75992e 100755
--- a/sysroots/i686-unknown-linux-musl/lib/libc++.so
+++ b/sysroots/i686-unknown-linux-musl/lib/libc++.so
Binary files differ
diff --git a/sysroots/i686-unknown-linux-musl/lib/libc++abi.a b/sysroots/i686-unknown-linux-musl/lib/libc++abi.a
index 935b31f..bf60fe1 100644
--- a/sysroots/i686-unknown-linux-musl/lib/libc++abi.a
+++ b/sysroots/i686-unknown-linux-musl/lib/libc++abi.a
Binary files differ
diff --git a/sysroots/i686-unknown-linux-musl/lib/libc.a b/sysroots/i686-unknown-linux-musl/lib/libc.a
index e02a61b..ba84624 100644
--- a/sysroots/i686-unknown-linux-musl/lib/libc.a
+++ b/sysroots/i686-unknown-linux-musl/lib/libc.a
Binary files differ
diff --git a/sysroots/i686-unknown-linux-musl/lib/libc_musl_linker_object.o b/sysroots/i686-unknown-linux-musl/lib/libc_musl_linker_object.o
index b1263bb..d61b7e8 100644
--- a/sysroots/i686-unknown-linux-musl/lib/libc_musl_linker_object.o
+++ b/sysroots/i686-unknown-linux-musl/lib/libc_musl_linker_object.o
Binary files differ
diff --git a/sysroots/i686-unknown-linux-musl/lib/libz.a b/sysroots/i686-unknown-linux-musl/lib/libz.a
index 1571745..f5679d7 100644
--- a/sysroots/i686-unknown-linux-musl/lib/libz.a
+++ b/sysroots/i686-unknown-linux-musl/lib/libz.a
Binary files differ
diff --git a/sysroots/i686-unknown-linux-musl/lib/rcrt1.o b/sysroots/i686-unknown-linux-musl/lib/rcrt1.o
index 7be009d..ec64d83 100644
--- a/sysroots/i686-unknown-linux-musl/lib/rcrt1.o
+++ b/sysroots/i686-unknown-linux-musl/lib/rcrt1.o
Binary files differ
diff --git a/sysroots/x86_64-unknown-linux-musl/lib/crt1.o b/sysroots/x86_64-unknown-linux-musl/lib/crt1.o
index 046b764..5169635 100644
--- a/sysroots/x86_64-unknown-linux-musl/lib/crt1.o
+++ b/sysroots/x86_64-unknown-linux-musl/lib/crt1.o
Binary files differ
diff --git a/sysroots/x86_64-unknown-linux-musl/lib/crtbegin.o b/sysroots/x86_64-unknown-linux-musl/lib/crtbegin.o
index a1f0db9..b8c901a 100755
--- a/sysroots/x86_64-unknown-linux-musl/lib/crtbegin.o
+++ b/sysroots/x86_64-unknown-linux-musl/lib/crtbegin.o
Binary files differ
diff --git a/sysroots/x86_64-unknown-linux-musl/lib/crtbeginS.o b/sysroots/x86_64-unknown-linux-musl/lib/crtbeginS.o
index a1f0db9..b8c901a 100755
--- a/sysroots/x86_64-unknown-linux-musl/lib/crtbeginS.o
+++ b/sysroots/x86_64-unknown-linux-musl/lib/crtbeginS.o
Binary files differ
diff --git a/sysroots/x86_64-unknown-linux-musl/lib/crtbeginT.o b/sysroots/x86_64-unknown-linux-musl/lib/crtbeginT.o
index a1f0db9..b8c901a 100755
--- a/sysroots/x86_64-unknown-linux-musl/lib/crtbeginT.o
+++ b/sysroots/x86_64-unknown-linux-musl/lib/crtbeginT.o
Binary files differ
diff --git a/sysroots/x86_64-unknown-linux-musl/lib/crtend.o b/sysroots/x86_64-unknown-linux-musl/lib/crtend.o
index c96e258..a40961c 100755
--- a/sysroots/x86_64-unknown-linux-musl/lib/crtend.o
+++ b/sysroots/x86_64-unknown-linux-musl/lib/crtend.o
Binary files differ
diff --git a/sysroots/x86_64-unknown-linux-musl/lib/crtendS.o b/sysroots/x86_64-unknown-linux-musl/lib/crtendS.o
index c96e258..a40961c 100755
--- a/sysroots/x86_64-unknown-linux-musl/lib/crtendS.o
+++ b/sysroots/x86_64-unknown-linux-musl/lib/crtendS.o
Binary files differ
diff --git a/sysroots/x86_64-unknown-linux-musl/lib/crti.o b/sysroots/x86_64-unknown-linux-musl/lib/crti.o
index f07f2b6..cadf5ca 100644
--- a/sysroots/x86_64-unknown-linux-musl/lib/crti.o
+++ b/sysroots/x86_64-unknown-linux-musl/lib/crti.o
Binary files differ
diff --git a/sysroots/x86_64-unknown-linux-musl/lib/crtn.o b/sysroots/x86_64-unknown-linux-musl/lib/crtn.o
index d8ef2d4..7033308 100644
--- a/sysroots/x86_64-unknown-linux-musl/lib/crtn.o
+++ b/sysroots/x86_64-unknown-linux-musl/lib/crtn.o
Binary files differ
diff --git a/sysroots/x86_64-unknown-linux-musl/lib/libc++.a b/sysroots/x86_64-unknown-linux-musl/lib/libc++.a
index add0e57..d7784ac 100644
--- a/sysroots/x86_64-unknown-linux-musl/lib/libc++.a
+++ b/sysroots/x86_64-unknown-linux-musl/lib/libc++.a
Binary files differ
diff --git a/sysroots/x86_64-unknown-linux-musl/lib/libc++.so b/sysroots/x86_64-unknown-linux-musl/lib/libc++.so
index 629e6b1..7c55bf9 100755
--- a/sysroots/x86_64-unknown-linux-musl/lib/libc++.so
+++ b/sysroots/x86_64-unknown-linux-musl/lib/libc++.so
Binary files differ
diff --git a/sysroots/x86_64-unknown-linux-musl/lib/libc++abi.a b/sysroots/x86_64-unknown-linux-musl/lib/libc++abi.a
index fdcbe51..4ddf557 100644
--- a/sysroots/x86_64-unknown-linux-musl/lib/libc++abi.a
+++ b/sysroots/x86_64-unknown-linux-musl/lib/libc++abi.a
Binary files differ
diff --git a/sysroots/x86_64-unknown-linux-musl/lib/libc.a b/sysroots/x86_64-unknown-linux-musl/lib/libc.a
index b872498..63cd7e7 100644
--- a/sysroots/x86_64-unknown-linux-musl/lib/libc.a
+++ b/sysroots/x86_64-unknown-linux-musl/lib/libc.a
Binary files differ
diff --git a/sysroots/x86_64-unknown-linux-musl/lib/libc_musl_linker_object.o b/sysroots/x86_64-unknown-linux-musl/lib/libc_musl_linker_object.o
index 52ac456..5f051c0 100644
--- a/sysroots/x86_64-unknown-linux-musl/lib/libc_musl_linker_object.o
+++ b/sysroots/x86_64-unknown-linux-musl/lib/libc_musl_linker_object.o
Binary files differ
diff --git a/sysroots/x86_64-unknown-linux-musl/lib/libz.a b/sysroots/x86_64-unknown-linux-musl/lib/libz.a
index ffaff2b..8d22c47 100644
--- a/sysroots/x86_64-unknown-linux-musl/lib/libz.a
+++ b/sysroots/x86_64-unknown-linux-musl/lib/libz.a
Binary files differ
diff --git a/sysroots/x86_64-unknown-linux-musl/lib/rcrt1.o b/sysroots/x86_64-unknown-linux-musl/lib/rcrt1.o
index 1dc0499..276efa0 100644
--- a/sysroots/x86_64-unknown-linux-musl/lib/rcrt1.o
+++ b/sysroots/x86_64-unknown-linux-musl/lib/rcrt1.o
Binary files differ