diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst
index 062ef3a1fea93c..a99de9904c0740 100644
--- a/Doc/c-api/code.rst
+++ b/Doc/c-api/code.rst
@@ -172,6 +172,11 @@ bound into a function.
before the destruction of *co* takes place, so the prior state of *co*
can be inspected.
+ If *event* is ``PY_CODE_EVENT_DESTROY``, taking a reference in the callback
+ to the about-to-be-destroyed code object will resurrect it and prevent it
+ from being freed at this time. When the resurrected object is destroyed
+ later, any watcher callbacks active at that time will be called again.
+
Users of this API should not rely on internal runtime implementation
details. Such details may include, but are not limited to, the exact
order and timing of creation and destruction of code objects. While
@@ -179,9 +184,15 @@ bound into a function.
(including whether a callback is invoked or not), it does not change
the semantics of the Python code being executed.
- If the callback returns with an exception set, it must return ``-1``; this
- exception will be printed as an unraisable exception using
- :c:func:`PyErr_WriteUnraisable`. Otherwise it should return ``0``.
+ If the callback sets an exception, it must return ``-1``; this exception will
+ be printed as an unraisable exception using :c:func:`PyErr_WriteUnraisable`.
+ Otherwise it should return ``0``.
+
+ There may already be a pending exception set on entry to the callback. In
+ this case, the callback should return ``0`` with the same exception still
+ set. This means the callback may not call any other API that can set an
+ exception unless it saves and clears the exception state first, and restores
+ it before returning.
.. versionadded:: 3.12
diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst
index 34106ee6b1f30d..b9f84cea785644 100644
--- a/Doc/c-api/dict.rst
+++ b/Doc/c-api/dict.rst
@@ -298,13 +298,26 @@ Dictionary Objects
dictionary.
The callback may inspect but must not modify *dict*; doing so could have
- unpredictable effects, including infinite recursion.
+ unpredictable effects, including infinite recursion. Do not trigger Python
+ code execution in the callback, as it could modify the dict as a side effect.
+
+ If *event* is ``PyDict_EVENT_DEALLOCATED``, taking a new reference in the
+ callback to the about-to-be-destroyed dictionary will resurrect it and
+ prevent it from being freed at this time. When the resurrected object is
+ destroyed later, any watcher callbacks active at that time will be called
+ again.
Callbacks occur before the notified modification to *dict* takes place, so
the prior state of *dict* can be inspected.
- If the callback returns with an exception set, it must return ``-1``; this
- exception will be printed as an unraisable exception using
- :c:func:`PyErr_WriteUnraisable`. Otherwise it should return ``0``.
+ If the callback sets an exception, it must return ``-1``; this exception will
+ be printed as an unraisable exception using :c:func:`PyErr_WriteUnraisable`.
+ Otherwise it should return ``0``.
+
+ There may already be a pending exception set on entry to the callback. In
+ this case, the callback should return ``0`` with the same exception still
+ set. This means the callback may not call any other API that can set an
+ exception unless it saves and clears the exception state first, and restores
+ it before returning.
.. versionadded:: 3.12
diff --git a/Doc/c-api/function.rst b/Doc/c-api/function.rst
index bc7569d0add97d..947ed70404081b 100644
--- a/Doc/c-api/function.rst
+++ b/Doc/c-api/function.rst
@@ -173,8 +173,19 @@ There are a few functions specific to Python functions.
runtime behavior depending on optimization decisions, it does not change
the semantics of the Python code being executed.
- If the callback returns with an exception set, it must return ``-1``; this
- exception will be printed as an unraisable exception using
- :c:func:`PyErr_WriteUnraisable`. Otherwise it should return ``0``.
+ If *event* is ``PyFunction_EVENT_DESTROY``, Taking a reference in the
+ callback to the about-to-be-destroyed function will resurrect it, preventing
+ it from being freed at this time. When the resurrected object is destroyed
+ later, any watcher callbacks active at that time will be called again.
+
+ If the callback sets an exception, it must return ``-1``; this exception will
+ be printed as an unraisable exception using :c:func:`PyErr_WriteUnraisable`.
+ Otherwise it should return ``0``.
+
+ There may already be a pending exception set on entry to the callback. In
+ this case, the callback should return ``0`` with the same exception still
+ set. This means the callback may not call any other API that can set an
+ exception unless it saves and clears the exception state first, and restores
+ it before returning.
.. versionadded:: 3.12
diff --git a/Doc/distributing/index.rst b/Doc/distributing/index.rst
index 2ae2726d4e4b92..21389adedf9c15 100644
--- a/Doc/distributing/index.rst
+++ b/Doc/distributing/index.rst
@@ -39,8 +39,7 @@ Key terms
developers and documentation authors responsible for the maintenance and
evolution of the standard packaging tools and the associated metadata and
file format standards. They maintain a variety of tools, documentation
- and issue trackers on both `GitHub ~https://github.com/pypa>`__ and
- `Bitbucket `__.
+ and issue trackers on `GitHub ~https://github.com/pypa>`__.
* ``distutils`` is the original build and distribution system first added
to the Python standard library in 1998. While direct use of ``distutils``
is being phased out, it still laid the foundation for the current packaging
diff --git a/Doc/installing/index.rst b/Doc/installing/index.rst
index e158bf1c4c0c7f..5aec5178d48f3d 100644
--- a/Doc/installing/index.rst
+++ b/Doc/installing/index.rst
@@ -52,8 +52,7 @@ Key terms
developers and documentation authors responsible for the maintenance and
evolution of the standard packaging tools and the associated metadata and
file format standards. They maintain a variety of tools, documentation,
- and issue trackers on both `GitHub ~https://github.com/pypa>`__ and
- `Bitbucket `__.
+ and issue trackers on `GitHub ~https://github.com/pypa>`__.
* ``distutils`` is the original build and distribution system first added to
the Python standard library in 1998. While direct use of ``distutils`` is
being phased out, it still laid the foundation for the current packaging
diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst
index 34b4c61649b99f..ee68ac58d3de75 100644
--- a/Doc/library/argparse.rst
+++ b/Doc/library/argparse.rst
@@ -34,9 +34,9 @@ around an instance of :class:`argparse.ArgumentParser`. It is a container for
argument specifications and has options that apply to the parser as whole::
parser = argparse.ArgumentParser(
- prog = 'ProgramName',
- description = 'What the program does',
- epilog = 'Text at the bottom of help')
+ prog='ProgramName',
+ description='What the program does',
+ epilog='Text at the bottom of help')
The :meth:`ArgumentParser.add_argument` method attaches individual argument
specifications to the parser. It supports positional arguments, options that
diff --git a/Doc/library/venv.rst b/Doc/library/venv.rst
index 2a41096de006b8..8eb0b35eaa12df 100644
--- a/Doc/library/venv.rst
+++ b/Doc/library/venv.rst
@@ -478,7 +478,7 @@ subclass which installs setuptools and pip into a created virtual environment::
:param context: The information for the virtual environment
creation request being processed.
"""
- url = 'https://bitbucket.org/pypa/setuptools/downloads/ez_setup.py'
+ url = "https://bootstrap.pypa.io/ez_setup.py"
self.install_script(context, 'setuptools', url)
# clear up the setuptools archive which gets downloaded
pred = lambda o: o.startswith('setuptools-') and o.endswith('.tar.gz')
diff --git a/Doc/library/zipapp.rst b/Doc/library/zipapp.rst
index fb40a2b3e964e4..981020b13cd988 100644
--- a/Doc/library/zipapp.rst
+++ b/Doc/library/zipapp.rst
@@ -215,7 +215,7 @@ using the :func:`create_archive` function::
>>> import zipapp
>>> zipapp.create_archive('old_archive.pyz', 'new_archive.pyz', '/usr/bin/python3')
-To update the file in place, do the replacement in memory using a :class:`BytesIO`
+To update the file in place, do the replacement in memory using a :class:`~io.BytesIO`
object, and then overwrite the source afterwards. Note that there is a risk
when overwriting a file in place that an error will result in the loss of
the original file. This code does not protect against such errors, but
diff --git a/Doc/library/zipfile.rst b/Doc/library/zipfile.rst
index 0195abc3a992c1..e2a085d6e98e67 100644
--- a/Doc/library/zipfile.rst
+++ b/Doc/library/zipfile.rst
@@ -288,7 +288,7 @@ ZipFile Objects
(``ZipExtFile``) is read-only and provides the following methods:
:meth:`~io.BufferedIOBase.read`, :meth:`~io.IOBase.readline`,
:meth:`~io.IOBase.readlines`, :meth:`~io.IOBase.seek`,
- :meth:`~io.IOBase.tell`, :meth:`__iter__`, :meth:`~iterator.__next__`.
+ :meth:`~io.IOBase.tell`, :meth:`~container.__iter__`, :meth:`~iterator.__next__`.
These objects can operate independently of the ZipFile.
With ``mode='w'``, a writable file handle is returned, which supports the
diff --git a/Include/cpython/code.h b/Include/cpython/code.h
index 0e4bd8a58c165b..abcf1250603dfe 100644
--- a/Include/cpython/code.h
+++ b/Include/cpython/code.h
@@ -224,9 +224,14 @@ PyAPI_FUNC(int) PyCode_Addr2Line(PyCodeObject *, int);
PyAPI_FUNC(int) PyCode_Addr2Location(PyCodeObject *, int, int *, int *, int *, int *);
-typedef enum PyCodeEvent {
- PY_CODE_EVENT_CREATE,
- PY_CODE_EVENT_DESTROY
+#define PY_FOREACH_CODE_EVENT(V) \
+ V(CREATE) \
+ V(DESTROY)
+
+typedef enum {
+ #define PY_DEF_EVENT(op) PY_CODE_EVENT_##op,
+ PY_FOREACH_CODE_EVENT(PY_DEF_EVENT)
+ #undef PY_DEF_EVENT
} PyCodeEvent;
@@ -236,7 +241,7 @@ typedef enum PyCodeEvent {
* The callback is invoked with a borrowed reference to co, after it is
* created and before it is destroyed.
*
- * If the callback returns with an exception set, it must return -1. Otherwise
+ * If the callback sets an exception, it must return -1. Otherwise
* it should return 0.
*/
typedef int (*PyCode_WatchCallback)(
diff --git a/Include/cpython/dictobject.h b/Include/cpython/dictobject.h
index 5001f35654475e..ddada922020aa4 100644
--- a/Include/cpython/dictobject.h
+++ b/Include/cpython/dictobject.h
@@ -16,11 +16,11 @@ typedef struct {
/* Dictionary version: globally unique, value change each time
the dictionary is modified */
-#ifdef Py_BUILD_CORE
+#ifdef Py_BUILD_CORE
uint64_t ma_version_tag;
#else
Py_DEPRECATED(3.12) uint64_t ma_version_tag;
-#endif
+#endif
PyDictKeysObject *ma_keys;
@@ -90,13 +90,18 @@ PyAPI_FUNC(PyObject *) _PyDictView_Intersect(PyObject* self, PyObject *other);
/* Dictionary watchers */
+#define PY_FOREACH_DICT_EVENT(V) \
+ V(ADDED) \
+ V(MODIFIED) \
+ V(DELETED) \
+ V(CLONED) \
+ V(CLEARED) \
+ V(DEALLOCATED)
+
typedef enum {
- PyDict_EVENT_ADDED,
- PyDict_EVENT_MODIFIED,
- PyDict_EVENT_DELETED,
- PyDict_EVENT_CLONED,
- PyDict_EVENT_CLEARED,
- PyDict_EVENT_DEALLOCATED,
+ #define PY_DEF_EVENT(EVENT) PyDict_EVENT_##EVENT,
+ PY_FOREACH_DICT_EVENT(PY_DEF_EVENT)
+ #undef PY_DEF_EVENT
} PyDict_WatchEvent;
// Callback to be invoked when a watched dict is cleared, dealloced, or modified.
diff --git a/Include/cpython/funcobject.h b/Include/cpython/funcobject.h
index 5979febc2e3421..c716330cc3fbab 100644
--- a/Include/cpython/funcobject.h
+++ b/Include/cpython/funcobject.h
@@ -131,17 +131,17 @@ PyAPI_DATA(PyTypeObject) PyStaticMethod_Type;
PyAPI_FUNC(PyObject *) PyClassMethod_New(PyObject *);
PyAPI_FUNC(PyObject *) PyStaticMethod_New(PyObject *);
-#define FOREACH_FUNC_EVENT(V) \
- V(CREATE) \
- V(DESTROY) \
- V(MODIFY_CODE) \
- V(MODIFY_DEFAULTS) \
+#define PY_FOREACH_FUNC_EVENT(V) \
+ V(CREATE) \
+ V(DESTROY) \
+ V(MODIFY_CODE) \
+ V(MODIFY_DEFAULTS) \
V(MODIFY_KWDEFAULTS)
typedef enum {
- #define DEF_EVENT(EVENT) PyFunction_EVENT_##EVENT,
- FOREACH_FUNC_EVENT(DEF_EVENT)
- #undef DEF_EVENT
+ #define PY_DEF_EVENT(EVENT) PyFunction_EVENT_##EVENT,
+ PY_FOREACH_FUNC_EVENT(PY_DEF_EVENT)
+ #undef PY_DEF_EVENT
} PyFunction_WatchEvent;
/*
diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h
index c74a3437713039..1af5e59a677a9a 100644
--- a/Include/internal/pycore_dict.h
+++ b/Include/internal/pycore_dict.h
@@ -164,6 +164,7 @@ _PyDict_NotifyEvent(PyDict_WatchEvent event,
PyObject *key,
PyObject *value)
{
+ assert(Py_REFCNT((PyObject*)mp) > 0);
int watcher_bits = mp->ma_version_tag & DICT_VERSION_MASK;
if (watcher_bits) {
_PyDict_SendEvent(watcher_bits, event, mp, key, value);
diff --git a/Include/patchlevel.h b/Include/patchlevel.h
index 7957220ed7cf9f..049cdfa30897ca 100644
--- a/Include/patchlevel.h
+++ b/Include/patchlevel.h
@@ -20,10 +20,10 @@
#define PY_MINOR_VERSION 12
#define PY_MICRO_VERSION 0
#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA
-#define PY_RELEASE_SERIAL 5
+#define PY_RELEASE_SERIAL 6
/* Version as a string */
-#define PY_VERSION "3.12.0a5+"
+#define PY_VERSION "3.12.0a6+"
/*--end constants--*/
/* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2.
diff --git a/Lib/_pylong.py b/Lib/_pylong.py
index d14c1d93836327..936346e187ff69 100644
--- a/Lib/_pylong.py
+++ b/Lib/_pylong.py
@@ -12,7 +12,6 @@
tricky or non-obvious code is not worth it. For people looking for
maximum performance, they should use something like gmpy2."""
-import sys
import re
import decimal
diff --git a/Lib/concurrent/futures/process.py b/Lib/concurrent/futures/process.py
index bee162430a6f8e..3a8637b6fa1b47 100644
--- a/Lib/concurrent/futures/process.py
+++ b/Lib/concurrent/futures/process.py
@@ -49,6 +49,8 @@
from concurrent.futures import _base
import queue
import multiprocessing as mp
+# This import is required to load the multiprocessing.connection submodule
+# so that it can be accessed later as `mp.connection`
import multiprocessing.connection
from multiprocessing.queues import Queue
import threading
diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py
index 5c0257eba186d1..8bc8594d674bc0 100644
--- a/Lib/dataclasses.py
+++ b/Lib/dataclasses.py
@@ -4,7 +4,6 @@
import types
import inspect
import keyword
-import builtins
import functools
import itertools
import abc
diff --git a/Lib/importlib/_abc.py b/Lib/importlib/_abc.py
index 08320563896521..693b466112638f 100644
--- a/Lib/importlib/_abc.py
+++ b/Lib/importlib/_abc.py
@@ -1,7 +1,6 @@
"""Subset of importlib.abc used to reduce importlib.util imports."""
from . import _bootstrap
import abc
-import warnings
class Loader(metaclass=abc.ABCMeta):
diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py
index e7f403d3ffbf12..573065b4b714d9 100644
--- a/Lib/pydoc_data/topics.py
+++ b/Lib/pydoc_data/topics.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Autogenerated by Sphinx on Tue Feb 7 13:18:04 2023
+# Autogenerated by Sphinx on Tue Mar 7 22:42:28 2023
topics = {'assert': 'The "assert" statement\n'
'**********************\n'
'\n'
@@ -2499,42 +2499,33 @@
'alive\n'
'until the next garbage collection occurs.\n'
'\n'
- 'Before an "except" clause’s suite is executed, details about '
- 'the\n'
- 'exception are stored in the "sys" module and can be accessed '
- 'via\n'
- '"sys.exc_info()". "sys.exc_info()" returns a 3-tuple consisting '
- 'of the\n'
- 'exception class, the exception instance and a traceback object '
- '(see\n'
- 'section The standard type hierarchy) identifying the point in '
- 'the\n'
- 'program where the exception occurred. The details about the '
- 'exception\n'
- 'accessed via "sys.exc_info()" are restored to their previous '
- 'values\n'
- 'when leaving an exception handler:\n'
+ 'Before an "except" clause’s suite is executed, the exception is '
+ 'stored\n'
+ 'in the "sys" module, where it can be accessed from within the '
+ 'body of\n'
+ 'the "except" clause by calling "sys.exception()". When leaving '
+ 'an\n'
+ 'exception handler, the exception stored in the "sys" module is '
+ 'reset\n'
+ 'to its previous value:\n'
'\n'
- ' >>> print(sys.exc_info())\n'
- ' (None, None, None)\n'
+ ' >>> print(sys.exception())\n'
+ ' None\n'
' >>> try:\n'
' ... raise TypeError\n'
' ... except:\n'
- ' ... print(sys.exc_info())\n'
+ ' ... print(repr(sys.exception()))\n'
' ... try:\n'
' ... raise ValueError\n'
' ... except:\n'
- ' ... print(sys.exc_info())\n'
- ' ... print(sys.exc_info())\n'
+ ' ... print(repr(sys.exception()))\n'
+ ' ... print(repr(sys.exception()))\n'
' ...\n'
- " (, TypeError(), )\n'
- " (, ValueError(), )\n'
- " (, TypeError(), )\n'
- ' >>> print(sys.exc_info())\n'
- ' (None, None, None)\n'
+ ' TypeError()\n'
+ ' ValueError()\n'
+ ' TypeError()\n'
+ ' >>> print(sys.exception())\n'
+ ' None\n'
'\n'
'\n'
'"except*" clause\n'
@@ -4533,7 +4524,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'
@@ -9453,7 +9444,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'
@@ -12644,37 +12635,31 @@
'cycle with the stack frame, keeping all locals in that frame alive\n'
'until the next garbage collection occurs.\n'
'\n'
- 'Before an "except" clause’s suite is executed, details about the\n'
- 'exception are stored in the "sys" module and can be accessed via\n'
- '"sys.exc_info()". "sys.exc_info()" returns a 3-tuple consisting of '
- 'the\n'
- 'exception class, the exception instance and a traceback object (see\n'
- 'section The standard type hierarchy) identifying the point in the\n'
- 'program where the exception occurred. The details about the '
- 'exception\n'
- 'accessed via "sys.exc_info()" are restored to their previous values\n'
- 'when leaving an exception handler:\n'
+ 'Before an "except" clause’s suite is executed, the exception is '
+ 'stored\n'
+ 'in the "sys" module, where it can be accessed from within the body '
+ 'of\n'
+ 'the "except" clause by calling "sys.exception()". When leaving an\n'
+ 'exception handler, the exception stored in the "sys" module is reset\n'
+ 'to its previous value:\n'
'\n'
- ' >>> print(sys.exc_info())\n'
- ' (None, None, None)\n'
+ ' >>> print(sys.exception())\n'
+ ' None\n'
' >>> try:\n'
' ... raise TypeError\n'
' ... except:\n'
- ' ... print(sys.exc_info())\n'
+ ' ... print(repr(sys.exception()))\n'
' ... try:\n'
' ... raise ValueError\n'
' ... except:\n'
- ' ... print(sys.exc_info())\n'
- ' ... print(sys.exc_info())\n'
+ ' ... print(repr(sys.exception()))\n'
+ ' ... print(repr(sys.exception()))\n'
' ...\n'
- " (, TypeError(), )\n'
- " (, ValueError(), )\n'
- " (, TypeError(), )\n'
- ' >>> print(sys.exc_info())\n'
- ' (None, None, None)\n'
+ ' TypeError()\n'
+ ' ValueError()\n'
+ ' TypeError()\n'
+ ' >>> print(sys.exception())\n'
+ ' None\n'
'\n'
'\n'
'"except*" clause\n'
@@ -14408,7 +14393,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 '
diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py
index c61100a6da8503..122d441bd19f5e 100644
--- a/Lib/sysconfig.py
+++ b/Lib/sysconfig.py
@@ -3,7 +3,7 @@
import os
import sys
import threading
-from os.path import pardir, realpath
+from os.path import realpath
__all__ = [
'get_config_h_filename',
diff --git a/Lib/test/_test_venv_multiprocessing.py b/Lib/test/_test_venv_multiprocessing.py
index 044a0c6cd3f5ca..ad985dd8d56bb4 100644
--- a/Lib/test/_test_venv_multiprocessing.py
+++ b/Lib/test/_test_venv_multiprocessing.py
@@ -1,7 +1,6 @@
import multiprocessing
import random
import sys
-import time
def fill_queue(queue, code):
queue.put(code)
diff --git a/Lib/test/fork_wait.py b/Lib/test/fork_wait.py
index c26c7aaaeb4306..8c32895f5e09e5 100644
--- a/Lib/test/fork_wait.py
+++ b/Lib/test/fork_wait.py
@@ -9,7 +9,7 @@
active threads survive in the child after a fork(); this is an error.
"""
-import os, sys, time, unittest
+import os, time, unittest
import threading
from test import support
from test.support import threading_helper
diff --git a/Lib/test/test__xxinterpchannels.py b/Lib/test/test__xxinterpchannels.py
index 03bb5c80b8dac9..69bda89a1688f5 100644
--- a/Lib/test/test__xxinterpchannels.py
+++ b/Lib/test/test__xxinterpchannels.py
@@ -1,6 +1,5 @@
from collections import namedtuple
import contextlib
-import os
import sys
from textwrap import dedent
import threading
diff --git a/Lib/test/test__xxsubinterpreters.py b/Lib/test/test__xxsubinterpreters.py
index 687fcf3b770522..965967e3f2734b 100644
--- a/Lib/test/test__xxsubinterpreters.py
+++ b/Lib/test/test__xxsubinterpreters.py
@@ -1,4 +1,3 @@
-from collections import namedtuple
import contextlib
import itertools
import os
@@ -6,7 +5,6 @@
import sys
from textwrap import dedent
import threading
-import time
import unittest
import _testcapi
diff --git a/Lib/test/test_asyncgen.py b/Lib/test/test_asyncgen.py
index 0421efdbf9dac9..09e4010b0e53d6 100644
--- a/Lib/test/test_asyncgen.py
+++ b/Lib/test/test_asyncgen.py
@@ -2,7 +2,6 @@
import types
import unittest
import contextlib
-import warnings
from test.support.import_helper import import_module
from test.support import gc_collect, requires_working_socket
diff --git a/Lib/test/test_asyncio/test_ssl.py b/Lib/test/test_asyncio/test_ssl.py
index aaf3c37101f52a..e9cc735613fb8e 100644
--- a/Lib/test/test_asyncio/test_ssl.py
+++ b/Lib/test/test_asyncio/test_ssl.py
@@ -1,5 +1,4 @@
import asyncio
-import asyncio.sslproto
import contextlib
import gc
import logging
diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py
index f1ad10a9903fe8..eba6e2d1f28f3e 100644
--- a/Lib/test/test_asyncio/test_subprocess.py
+++ b/Lib/test/test_asyncio/test_subprocess.py
@@ -1,5 +1,4 @@
import os
-import shutil
import signal
import sys
import unittest
diff --git a/Lib/test/test_capi/test_exceptions.py b/Lib/test/test_capi/test_exceptions.py
index b543a1a565a56f..55f131699a2567 100644
--- a/Lib/test/test_capi/test_exceptions.py
+++ b/Lib/test/test_capi/test_exceptions.py
@@ -140,6 +140,34 @@ def test_err_restore(self):
self.assertEqual(1, v.args[0])
self.assertIs(tb, v.__traceback__.tb_next)
+ def test_set_object(self):
+
+ # new exception as obj is not an exception
+ with self.assertRaises(ValueError) as e:
+ _testcapi.exc_set_object(ValueError, 42)
+ self.assertEqual(e.exception.args, (42,))
+
+ # wraps the exception because unrelated types
+ with self.assertRaises(ValueError) as e:
+ _testcapi.exc_set_object(ValueError, TypeError(1,2,3))
+ wrapped = e.exception.args[0]
+ self.assertIsInstance(wrapped, TypeError)
+ self.assertEqual(wrapped.args, (1, 2, 3))
+
+ # is superclass, so does not wrap
+ with self.assertRaises(PermissionError) as e:
+ _testcapi.exc_set_object(OSError, PermissionError(24))
+ self.assertEqual(e.exception.args, (24,))
+
+ class Meta(type):
+ def __subclasscheck__(cls, sub):
+ 1/0
+
+ class Broken(Exception, metaclass=Meta):
+ pass
+
+ with self.assertRaises(ZeroDivisionError) as e:
+ _testcapi.exc_set_object(Broken, Broken())
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/test/test_capi/test_watchers.py b/Lib/test/test_capi/test_watchers.py
index 1922614ef60558..93f6ef752d0663 100644
--- a/Lib/test/test_capi/test_watchers.py
+++ b/Lib/test/test_capi/test_watchers.py
@@ -109,10 +109,21 @@ def test_error(self):
self.watch(wid, d)
with catch_unraisable_exception() as cm:
d["foo"] = "bar"
- self.assertIs(cm.unraisable.object, d)
+ self.assertIn(
+ "PyDict_EVENT_ADDED watcher callback for `_.
+
+..
+
+.. date: 2023-02-08-12-57-35
+.. gh-issue: 99108
+.. nonce: 6tnmhA
+.. section: Security
+
+Replace the builtin :mod:`hashlib` implementations of SHA2-384 and SHA2-512
+originally from LibTomCrypt with formally verified, side-channel resistant
+code from the `HACL* ~https://github.com/hacl-star/hacl-star/>`_ project.
+The builtins remain a fallback only used when OpenSSL does not provide them.
+
+..
+
+.. date: 2023-01-24-16-12-00
+.. gh-issue: 101283
+.. nonce: 9tqu39
+.. section: Security
+
+:class:`subprocess.Popen` now uses a safer approach to find ``cmd.exe`` when
+launching with ``shell=True``. Patch by Eryk Sun, based on a patch by Oleg
+Iarygin.
+
+..
+
+.. date: 2023-03-07-16-56-28
+.. gh-issue: 102493
+.. nonce: gTXrcD
+.. section: Core and Builtins
+
+Fix regression in semantics of normalisation in ``PyErr_SetObject``.
+
+..
+
+.. date: 2023-03-06-13-05-33
+.. gh-issue: 102416
+.. nonce: dz6K5f
+.. section: Core and Builtins
+
+Do not memoize incorrectly automatically generated loop rules in the parser.
+Patch by Pablo Galindo.
+
+..
+
+.. date: 2023-03-04-20-56-12
+.. gh-issue: 102356
+.. nonce: 07KvUd
+.. section: Core and Builtins
+
+Fix a bug that caused a crash when deallocating deeply nested filter
+objects. Patch by Marta Gómez Macías.
+
+..
+
+.. date: 2023-02-28-21-17-03
+.. gh-issue: 102336
+.. nonce: -wL3Tm
+.. section: Core and Builtins
+
+Cleanup Windows 7 specific special handling. Patch by Max Bachmann.
+
+..
+
+.. date: 2023-02-26-23-10-32
+.. gh-issue: 102250
+.. nonce: 7MUKoC
+.. section: Core and Builtins
+
+Fixed a segfault occurring when the interpreter calls a ``__bool__`` method
+that raises.
+
+..
+
+.. date: 2023-02-24-17-59-39
+.. gh-issue: 102126
+.. nonce: HTT8Vc
+.. section: Core and Builtins
+
+Fix deadlock at shutdown when clearing thread states if any finalizer tries
+to acquire the runtime head lock. Patch by Kumar Aditya.
+
+..
+
+.. date: 2023-02-22-15-15-32
+.. gh-issue: 102027
+.. nonce: Km4G-d
+.. section: Core and Builtins
+
+Use ``GetCurrentProcessId`` on Windows when ``getpid`` is unavailable. Patch
+by Max Bachmann.
+
+..
+
+.. date: 2023-02-20-15-18-33
+.. gh-issue: 102056
+.. nonce: uHKuwH
+.. section: Core and Builtins
+
+Fix error handling bugs in interpreter's exception printing code, which
+could cause a crash on infinite recursion.
+
+..
+
+.. date: 2023-02-17-10-12-13
+.. gh-issue: 100982
+.. nonce: mJGJQw
+.. section: Core and Builtins
+
+Restrict the scope of the :opcode:`FOR_ITER_RANGE` instruction to the scope
+of the original :opcode:`FOR_ITER` instruction, to allow instrumentation.
+
+..
+
+.. date: 2023-02-16-23-19-01
+.. gh-issue: 101967
+.. nonce: Kqr1dz
+.. section: Core and Builtins
+
+Fix possible segfault in ``positional_only_passed_as_keyword`` function,
+when new list created.
+
+..
+
+.. date: 2023-02-16-16-57-23
+.. gh-issue: 101952
+.. nonce: Zo1dlq
+.. section: Core and Builtins
+
+Fix possible segfault in ``BUILD_SET`` opcode, when new set created.
+
+..
+
+.. date: 2023-02-13-22-21-58
+.. gh-issue: 74895
+.. nonce: esMNtq
+.. section: Core and Builtins
+
+:mod:`socket.getaddrinfo` no longer raises :class:`OverflowError` for
+:class:`int` **port** values outside of the C long range. Out of range
+values are left up to the underlying string based C library API to report. A
+:class:`socket.gaierror` ``SAI_SERVICE`` may occur instead, or no error at
+all as not all platform C libraries generate an error.
+
+..
+
+.. date: 2023-02-13-18-21-14
+.. gh-issue: 101799
+.. nonce: wpHbCn
+.. section: Core and Builtins
+
+Add :opcode:`CALL_INTRINSIC_2` and use it instead of
+:opcode:`PREP_RERAISE_STAR`.
+
+..
+
+.. date: 2023-02-12-22-40-22
+.. gh-issue: 101857
+.. nonce: _bribG
+.. section: Core and Builtins
+
+Fix xattr support detection on Linux systems by widening the check to linux,
+not just glibc. This fixes support for musl.
+
+..
+
+.. date: 2023-02-11-23-14-06
+.. gh-issue: 84783
+.. nonce: _P5sMa
+.. section: Core and Builtins
+
+Make the slice object hashable.
+
+..
+
+.. date: 2023-02-10-15-54-57
+.. gh-issue: 87849
+.. nonce: IUVvPz
+.. section: Core and Builtins
+
+Change the ``SEND`` instruction to leave the receiver on the stack. This
+allows the specialized form of ``SEND`` to skip the chain of C calls and
+jump directly to the ``RESUME`` in the generator or coroutine.
+
+..
+
+.. date: 2023-02-10-07-21-47
+.. gh-issue: 101765
+.. nonce: MO5LlC
+.. section: Core and Builtins
+
+Fix SystemError / segmentation fault in iter ``__reduce__`` when internal
+access of ``builtins.__dict__`` keys mutates the iter object.
+
+..
+
+.. date: 2023-02-10-01-15-57
+.. gh-issue: 101430
+.. nonce: T3Gegb
+.. section: Core and Builtins
+
+Update :mod:`tracemalloc` to handle presize of object properly. Patch by
+Dong-hee Na.
+
+..
+
+.. date: 2023-02-08-17-13-31
+.. gh-issue: 101696
+.. nonce: seJhTt
+.. section: Core and Builtins
+
+Invalidate type version tag in ``_PyStaticType_Dealloc`` for static types,
+avoiding bug where a false cache hit could crash the interpreter. Patch by
+Kumar Aditya.
+
+..
+
+.. date: 2023-02-07-14-56-43
+.. gh-issue: 101632
+.. nonce: Fd1yxk
+.. section: Core and Builtins
+
+Adds a new :opcode:`RETURN_CONST` instruction.
+
+..
+
+.. date: 2023-01-04-12-49-33
+.. gh-issue: 100719
+.. nonce: uRPccL
+.. section: Core and Builtins
+
+Remove gi_code field from generator (and coroutine and async generator)
+objects as it is redundant. The frame already includes a reference to the
+code object.
+
+..
+
+.. date: 2022-11-02-20-23-47
+.. gh-issue: 98627
+.. nonce: VJkdRM
+.. section: Core and Builtins
+
+When an interpreter is configured to check (and only then), importing an
+extension module will now fail when the extension does not support multiple
+interpreters (i.e. doesn't implement PEP 489 multi-phase init). This does
+not apply to the main interpreter, nor to subinterpreters created with
+``Py_NewInterpreter()``.
+
+..
+
+.. date: 2023-03-04-14-46-47
+.. gh-issue: 102302
+.. nonce: -b_s6Z
+.. section: Library
+
+Micro-optimise hashing of :class:`inspect.Parameter`, reducing the time it
+takes to hash an instance by around 40%.
+
+..
+
+.. date: 2023-02-28-09-52-25
+.. gh-issue: 101979
+.. nonce: or3hXV
+.. section: Library
+
+Fix a bug where parentheses in the ``metavar`` argument to
+:meth:`argparse.ArgumentParser.add_argument` were dropped. Patch by Yeojin
+Kim.
+
+..
+
+.. date: 2023-02-26-12-37-17
+.. gh-issue: 91038
+.. nonce: S4rFH_
+.. section: Library
+
+:meth:`platform.platform` now has boolean default arguments.
+
+..
+
+.. date: 2023-02-23-20-39-52
+.. gh-issue: 81652
+.. nonce: Vxz0Mr
+.. section: Library
+
+Add :data:`mmap.MAP_ALIGNED_SUPER` FreeBSD and :data:`mmap.MAP_CONCEAL`
+OpenBSD constants to :mod:`mmap`. Patch by Yeojin Kim.
+
+..
+
+.. date: 2023-02-23-15-06-01
+.. gh-issue: 102179
+.. nonce: P6KQ4c
+.. section: Library
+
+Fix :func:`os.dup2` error message for negative fds.
+
+..
+
+.. date: 2023-02-21-10-05-33
+.. gh-issue: 101961
+.. nonce: 7e56jh
+.. section: Library
+
+For the binary mode, :func:`fileinput.hookcompressed` doesn't set the
+``encoding`` value even if the value is ``None``. Patch by Gihwan Kim.
+
+..
+
+.. date: 2023-02-21-07-15-41
+.. gh-issue: 101936
+.. nonce: QVOxHH
+.. section: Library
+
+The default value of ``fp`` becomes :class:`io.BytesIO` if
+:exc:`~urllib.error.HTTPError` is initialized without a designated ``fp``
+parameter. Patch by Long Vo.
+
+..
+
+.. date: 2023-02-17-20-24-15
+.. gh-issue: 101566
+.. nonce: FjgWBt
+.. section: Library
+
+In zipfile, sync Path with `zipp 3.14
+`_, including
+fix for extractall on the underlying zipfile after being wrapped in
+``Path``.
+
+..
+
+.. date: 2023-02-17-19-00-58
+.. gh-issue: 97930
+.. nonce: C_nQjb
+.. section: Library
+
+Apply changes from `importlib_resources 5.12
+`_,
+including fix for ``MultiplexedPath`` to support directories in multiple
+namespaces (python/importlib_resources#265).
+
+..
+
+.. date: 2023-02-17-18-44-27
+.. gh-issue: 101997
+.. nonce: A6_blD
+.. section: Library
+
+Upgrade pip wheel bundled with ensurepip (pip 23.0.1)
+
+..
+
+.. date: 2023-02-15-01-54-06
+.. gh-issue: 99108
+.. nonce: rjTSic
+.. section: Library
+
+The built-in extension modules for :mod:`hashlib` SHA2 algorithms, used when
+OpenSSL does not provide them, now live in a single internal ``_sha2``
+module instead of separate ``_sha256`` and ``_sha512`` modules.
+
+..
+
+.. date: 2023-02-14-09-08-48
+.. gh-issue: 101892
+.. nonce: FMos8l
+.. section: Library
+
+Callable iterators no longer raise :class:`SystemError` when the callable
+object exhausts the iterator but forgets to either return a sentinel value
+or raise :class:`StopIteration`.
+
+..
+
+.. date: 2023-02-13-12-55-48
+.. gh-issue: 87634
+.. nonce: q-SBhJ
+.. section: Library
+
+Remove locking behavior from :func:`functools.cached_property`.
+
+..
+
+.. date: 2023-02-11-13-23-29
+.. gh-issue: 97786
+.. nonce: QjvQ1B
+.. section: Library
+
+Fix potential undefined behaviour in corner cases of floating-point-to-time
+conversions.
+
+..
+
+.. date: 2023-02-10-16-02-29
+.. gh-issue: 101517
+.. nonce: r7S2u8
+.. section: Library
+
+Fixed bug where :mod:`bdb` looks up the source line with :mod:`linecache`
+with a ``lineno=None``, which causes it to fail with an unhandled exception.
+
+..
+
+.. date: 2023-02-10-11-59-13
+.. gh-issue: 101773
+.. nonce: J_kI7y
+.. section: Library
+
+Optimize :class:`fractions.Fraction` for small components. The private
+argument ``_normalize`` of the :class:`fractions.Fraction` constructor has
+been removed.
+
+..
+
+.. date: 2023-02-08-18-20-58
+.. gh-issue: 101693
+.. nonce: 4_LPXj
+.. section: Library
+
+In :meth:`sqlite3.Cursor.execute`, :exc:`DeprecationWarning` is now emitted
+when :ref:`named placeholders ` are used together with
+parameters supplied as a :term:`sequence` instead of as a :class:`dict`.
+Starting from Python 3.14, using named placeholders with parameters supplied
+as a sequence will raise a :exc:`~sqlite3.ProgrammingError`. Patch by Erlend
+E. Aasland.
+
+..
+
+.. date: 2023-02-07-22-21-46
+.. gh-issue: 101446
+.. nonce: -c0FdK
+.. section: Library
+
+Change repr of :class:`collections.OrderedDict` to use regular dictionary
+formating instead of pairs of keys and values.
+
+..
+
+.. date: 2023-02-07-22-20-32
+.. gh-issue: 101362
+.. nonce: Jlk6mt
+.. section: Library
+
+Speed up :class:`pathlib.PurePath` construction by handling arguments more
+uniformly. When a :class:`pathlib.Path` argument is supplied, we use its
+string representation rather than joining its parts with
+:func:`os.path.join`.
+
+..
+
+.. date: 2023-02-07-21-16-41
+.. gh-issue: 101362
+.. nonce: KMQllM
+.. section: Library
+
+Speed up :class:`pathlib.PurePath` construction by calling
+:func:`os.path.join` only when two or more arguments are given.
+
+..
+
+.. date: 2023-02-07-20-46-08
+.. gh-issue: 101362
+.. nonce: 2ckZ6R
+.. section: Library
+
+Speed up :class:`pathlib.Path` construction by running the path flavour
+compatibility check only when pathlib is imported.
+
+..
+
+.. date: 2023-02-05-21-40-15
+.. gh-issue: 85984
+.. nonce: Kfzbb2
+.. section: Library
+
+Refactored the implementation of :func:`pty.fork` to use
+:func:`os.login_tty`.
+
+A :exc:`DeprecationWarning` is now raised by ``pty.master_open()`` and
+``pty.slave_open()``. They were undocumented and deprecated long long ago in
+the docstring in favor of :func:`pty.openpty`.
+
+..
+
+.. date: 2023-02-04-16-35-46
+.. gh-issue: 101561
+.. nonce: Xo6pIZ
+.. section: Library
+
+Add a new decorator :func:`typing.override`. See :pep:`698` for details.
+Patch by Steven Troxler.
+
+..
+
+.. date: 2023-02-01-10-42-16
+.. gh-issue: 63301
+.. nonce: XNxSFh
+.. section: Library
+
+Set exit code when :mod:`tabnanny` CLI exits on error.
+
+..
+
+.. date: 2023-01-27-02-53-50
+.. gh-issue: 101360
+.. nonce: bPB7SL
+.. section: Library
+
+Fix anchor matching in :meth:`pathlib.PureWindowsPath.match`. Path and
+pattern anchors are now matched with :mod:`fnmatch`, just like other path
+parts. This allows patterns such as ``"*:/Users/*"`` to be matched.
+
+..
+
+.. date: 2023-01-25-00-14-52
+.. gh-issue: 101277
+.. nonce: FceHX7
+.. section: Library
+
+Remove global state from :mod:`itertools` module (:pep:`687`). Patches by
+Erlend E. Aasland.
+
+..
+
+.. date: 2023-01-06-21-14-41
+.. gh-issue: 100809
+.. nonce: I697UT
+.. section: Library
+
+Fix handling of drive-relative paths (like 'C:' and 'C:foo') in
+:meth:`pathlib.Path.absolute`. This method now uses the OS API to retrieve
+the correct current working directory for the drive.
+
+..
+
+.. date: 2023-01-02-22-41-44
+.. gh-issue: 99138
+.. nonce: 17hp9U
+.. section: Library
+
+Apply :pep:`687` to :mod:`zoneinfo`. Patch by Erlend E. Aasland.
+
+..
+
+.. date: 2022-10-22-09-26-43
+.. gh-issue: 96764
+.. nonce: Dh9Y5L
+.. section: Library
+
+:func:`asyncio.wait_for` now uses :func:`asyncio.timeout` as its underlying
+implementation. Patch by Kumar Aditya.
+
+..
+
+.. date: 2022-09-05-12-17-34
+.. gh-issue: 88233
+.. nonce: gff9qJ
+.. section: Library
+
+Correctly preserve "extra" fields in ``zipfile`` regardless of their
+ordering relative to a zip64 "extra."
+
+..
+
+.. bpo: 23224
+.. date: 2018-06-20-09-12-21
+.. nonce: zxCQ13
+.. section: Library
+
+Fix segfaults when creating :class:`lzma.LZMADecompressor` and
+:class:`bz2.BZ2Decompressor` objects without calling ``__init__()``, and fix
+leakage of locks and internal buffers when calling the ``__init__()``
+methods of :class:`lzma.LZMADecompressor`, :class:`lzma.LZMACompressor`,
+:class:`bz2.BZ2Compressor`, and :class:`bz2.BZ2Decompressor` objects
+multiple times.
+
+..
+
+.. date: 2023-02-19-10-33-01
+.. gh-issue: 85417
+.. nonce: kYO8u3
+.. section: Documentation
+
+Update :mod:`cmath` documentation to clarify behaviour on branch cuts.
+
+..
+
+.. date: 2023-02-07-21-43-24
+.. gh-issue: 97725
+.. nonce: cuY7Cd
+.. section: Documentation
+
+Fix :meth:`asyncio.Task.print_stack` description for ``file=None``. Patch by
+Oleg Iarygin.
+
+..
+
+.. date: 2023-02-18-10-51-02
+.. gh-issue: 102019
+.. nonce: 0797SJ
+.. section: Tests
+
+Fix deadlock on shutdown if ``test_current_{exception,frames}`` fails. Patch
+by Jacob Bower.
+
+..
+
+.. date: 2023-02-11-22-36-10
+.. gh-issue: 85984
+.. nonce: EVXjT9
+.. section: Tests
+
+Utilize new "winsize" functions from termios in pty tests.
+
+..
+
+.. date: 2023-02-11-20-28-08
+.. gh-issue: 89792
+.. nonce: S-Y5BZ
+.. section: Tests
+
+``test_tools`` now copies up to 10x less source data to a temporary
+directory during the ``freeze`` test by ignoring git metadata and other
+artifacts. It also limits its python build parallelism based on
+os.cpu_count instead of hard coding it as 8 cores.
+
+..
+
+.. date: 2023-01-12-00-49-16
+.. gh-issue: 99942
+.. nonce: DUR8b4
+.. section: Build
+
+On Android, in a static build, python-config in embed mode no longer
+incorrectly reports a library to link to.
+
+..
+
+.. date: 2022-12-20-01-06-17
+.. gh-issue: 99942
+.. nonce: lbmzYj
+.. section: Build
+
+On Android, python.pc now correctly reports the library to link to, the same
+as python-config.sh.
+
+..
+
+.. date: 2022-12-18-08-33-28
+.. gh-issue: 100221
+.. nonce: K94Ct3
+.. section: Build
+
+Fix creating install directories in ``make sharedinstall`` if they exist
+outside ``DESTDIR`` already.
+
+..
+
+.. date: 2022-09-14-10-38-15
+.. gh-issue: 96821
+.. nonce: Zk2a9c
+.. section: Build
+
+Explicitly mark C extension modules that need defined signed integer
+overflow, and add a configure option :option:`--with-strict-overflow`. Patch
+by Matthias Görgens and Shantanu Jain.
+
+..
+
+.. date: 2023-03-01-01-36-39
+.. gh-issue: 102344
+.. nonce: Dgfux4
+.. section: Windows
+
+Implement ``winreg.QueryValue`` using ``QueryValueEx`` and
+``winreg.SetValue`` using ``SetValueEx``. Patch by Max Bachmann.
+
+..
+
+.. date: 2023-02-15-11-08-10
+.. gh-issue: 101881
+.. nonce: fScr3m
+.. section: Windows
+
+Handle read and write operations on non-blocking pipes properly on Windows.
+
+..
+
+.. date: 2023-02-13-18-05-49
+.. gh-issue: 101881
+.. nonce: _TnHzN
+.. section: Windows
+
+Add support for the os.get_blocking() and os.set_blocking() functions on
+Windows.
+
+..
+
+.. date: 2023-02-13-16-32-50
+.. gh-issue: 101849
+.. nonce: 7lm_53
+.. section: Windows
+
+Ensures installer will correctly upgrade existing ``py.exe`` launcher
+installs.
+
+..
+
+.. date: 2023-02-10-14-26-05
+.. gh-issue: 101763
+.. nonce: RPaj7r
+.. section: Windows
+
+Updates copy of libffi bundled with Windows installs to 3.4.4.
+
+..
+
+.. date: 2023-02-09-22-09-27
+.. gh-issue: 101759
+.. nonce: zFlqSH
+.. section: Windows
+
+Update Windows installer to SQLite 3.40.1.
+
+..
+
+.. date: 2023-02-07-18-22-54
+.. gh-issue: 101614
+.. nonce: NjVP0n
+.. section: Windows
+
+Correctly handle extensions built against debug binaries that reference
+``python3_d.dll``.
+
+..
+
+.. date: 2023-01-25-11-33-54
+.. gh-issue: 101196
+.. nonce: wAX_2g
+.. section: Windows
+
+The functions ``os.path.isdir``, ``os.path.isfile``, ``os.path.islink`` and
+``os.path.exists`` are now 13% to 28% faster on Windows, by making fewer
+Win32 API calls.
+
+..
+
+.. date: 2023-02-09-22-07-17
+.. gh-issue: 101759
+.. nonce: B0JP2H
+.. section: macOS
+
+Update macOS installer to SQLite 3.40.1.
+
+..
+
+.. date: 2023-02-14-15-53-01
+.. gh-issue: 101907
+.. nonce: HgF1N2
+.. section: C API
+
+Removes use of non-standard C++ extension in public header files.
+
+..
+
+.. date: 2023-02-09-10-38-20
+.. gh-issue: 99293
+.. nonce: mFqfpp
+.. section: C API
+
+Document that the Py_TPFLAGS_VALID_VERSION_TAG is an internal feature,
+should not be used, and will be removed.
+
+..
+
+.. date: 2023-02-06-16-14-30
+.. gh-issue: 101578
+.. nonce: PW5fA9
+.. section: C API
+
+Add :c:func:`PyErr_GetRaisedException` and
+:c:func:`PyErr_SetRaisedException` for saving and restoring the current
+exception. These functions return and accept a single exception object,
+rather than the triple arguments of the now-deprecated :c:func:`PyErr_Fetch`
+and :c:func:`PyErr_Restore`. This is less error prone and a bit more
+efficient.
+
+Add :c:func:`PyException_GetArgs` and :c:func:`PyException_SetArgs` as
+convenience functions for retrieving and modifying the
+:attr:`~BaseException.args` passed to the exception's constructor.
+
+..
+
+.. date: 2022-04-21-17-25-22
+.. gh-issue: 91744
+.. nonce: FgvaMi
+.. section: C API
+
+Introduced the *Unstable C API tier*, marking APi that is allowed to change
+in minor releases without a deprecation period. See :pep:`689` for details.
diff --git a/Misc/NEWS.d/next/Build/2022-09-14-10-38-15.gh-issue-96821.Zk2a9c.rst b/Misc/NEWS.d/next/Build/2022-09-14-10-38-15.gh-issue-96821.Zk2a9c.rst
deleted file mode 100644
index 865cfde8b06359..00000000000000
--- a/Misc/NEWS.d/next/Build/2022-09-14-10-38-15.gh-issue-96821.Zk2a9c.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-Explicitly mark C extension modules that need defined signed integer overflow,
-and add a configure option :option:`--with-strict-overflow`.
-Patch by Matthias Görgens and Shantanu Jain.
diff --git a/Misc/NEWS.d/next/Build/2022-12-18-08-33-28.gh-issue-100221.K94Ct3.rst b/Misc/NEWS.d/next/Build/2022-12-18-08-33-28.gh-issue-100221.K94Ct3.rst
deleted file mode 100644
index 27c948330cfc17..00000000000000
--- a/Misc/NEWS.d/next/Build/2022-12-18-08-33-28.gh-issue-100221.K94Ct3.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Fix creating install directories in ``make sharedinstall`` if they exist
-outside ``DESTDIR`` already.
diff --git a/Misc/NEWS.d/next/Build/2022-12-20-01-06-17.gh-issue-99942.lbmzYj.rst b/Misc/NEWS.d/next/Build/2022-12-20-01-06-17.gh-issue-99942.lbmzYj.rst
deleted file mode 100644
index 63a640a9cdf733..00000000000000
--- a/Misc/NEWS.d/next/Build/2022-12-20-01-06-17.gh-issue-99942.lbmzYj.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-On Android, python.pc now correctly reports the library to link to, the same
-as python-config.sh.
diff --git a/Misc/NEWS.d/next/Build/2023-01-12-00-49-16.gh-issue-99942.DUR8b4.rst b/Misc/NEWS.d/next/Build/2023-01-12-00-49-16.gh-issue-99942.DUR8b4.rst
deleted file mode 100644
index 5b692c3cc458c5..00000000000000
--- a/Misc/NEWS.d/next/Build/2023-01-12-00-49-16.gh-issue-99942.DUR8b4.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-On Android, in a static build, python-config in embed mode no longer
-incorrectly reports a library to link to.
diff --git a/Misc/NEWS.d/next/C API/2022-04-21-17-25-22.gh-issue-91744.FgvaMi.rst b/Misc/NEWS.d/next/C API/2022-04-21-17-25-22.gh-issue-91744.FgvaMi.rst
deleted file mode 100644
index 20db25ddd0c1f6..00000000000000
--- a/Misc/NEWS.d/next/C API/2022-04-21-17-25-22.gh-issue-91744.FgvaMi.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-Introduced the *Unstable C API tier*, marking APi that is allowed to change
-in minor releases without a deprecation period.
-See :pep:`689` for details.
diff --git a/Misc/NEWS.d/next/C API/2023-02-06-16-14-30.gh-issue-101578.PW5fA9.rst b/Misc/NEWS.d/next/C API/2023-02-06-16-14-30.gh-issue-101578.PW5fA9.rst
deleted file mode 100644
index 27294a9e5179c4..00000000000000
--- a/Misc/NEWS.d/next/C API/2023-02-06-16-14-30.gh-issue-101578.PW5fA9.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Add :c:func:`PyErr_GetRaisedException` and :c:func:`PyErr_SetRaisedException`
-for saving and restoring the current exception.
-These functions return and accept a single exception object,
-rather than the triple arguments of the now-deprecated
-:c:func:`PyErr_Fetch` and :c:func:`PyErr_Restore`.
-This is less error prone and a bit more efficient.
-
-Add :c:func:`PyException_GetArgs` and :c:func:`PyException_SetArgs`
-as convenience functions for retrieving and modifying
-the :attr:`~BaseException.args` passed to the exception's constructor.
diff --git a/Misc/NEWS.d/next/C API/2023-02-09-10-38-20.gh-issue-99293.mFqfpp.rst b/Misc/NEWS.d/next/C API/2023-02-09-10-38-20.gh-issue-99293.mFqfpp.rst
deleted file mode 100644
index 8c0f05543747dc..00000000000000
--- a/Misc/NEWS.d/next/C API/2023-02-09-10-38-20.gh-issue-99293.mFqfpp.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Document that the Py_TPFLAGS_VALID_VERSION_TAG is an internal feature,
-should not be used, and will be removed.
diff --git a/Misc/NEWS.d/next/C API/2023-02-14-15-53-01.gh-issue-101907.HgF1N2.rst b/Misc/NEWS.d/next/C API/2023-02-14-15-53-01.gh-issue-101907.HgF1N2.rst
deleted file mode 100644
index cfc0d72cdbca00..00000000000000
--- a/Misc/NEWS.d/next/C API/2023-02-14-15-53-01.gh-issue-101907.HgF1N2.rst
+++ /dev/null
@@ -1 +0,0 @@
-Removes use of non-standard C++ extension in public header files.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-11-02-20-23-47.gh-issue-98627.VJkdRM.rst b/Misc/NEWS.d/next/Core and Builtins/2022-11-02-20-23-47.gh-issue-98627.VJkdRM.rst
deleted file mode 100644
index 3d2d6f6eb0c41f..00000000000000
--- a/Misc/NEWS.d/next/Core and Builtins/2022-11-02-20-23-47.gh-issue-98627.VJkdRM.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-When an interpreter is configured to check (and only then), importing an
-extension module will now fail when the extension does not support multiple
-interpreters (i.e. doesn't implement PEP 489 multi-phase init). This does
-not apply to the main interpreter, nor to subinterpreters created with
-``Py_NewInterpreter()``.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-01-04-12-49-33.gh-issue-100719.uRPccL.rst b/Misc/NEWS.d/next/Core and Builtins/2023-01-04-12-49-33.gh-issue-100719.uRPccL.rst
deleted file mode 100644
index 2addef27b8ea4d..00000000000000
--- a/Misc/NEWS.d/next/Core and Builtins/2023-01-04-12-49-33.gh-issue-100719.uRPccL.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-Remove gi_code field from generator (and coroutine and async generator)
-objects as it is redundant. The frame already includes a reference to the
-code object.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-02-07-14-56-43.gh-issue-101632.Fd1yxk.rst b/Misc/NEWS.d/next/Core and Builtins/2023-02-07-14-56-43.gh-issue-101632.Fd1yxk.rst
deleted file mode 100644
index 136909ca699903..00000000000000
--- a/Misc/NEWS.d/next/Core and Builtins/2023-02-07-14-56-43.gh-issue-101632.Fd1yxk.rst
+++ /dev/null
@@ -1 +0,0 @@
-Adds a new :opcode:`RETURN_CONST` instruction.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-02-08-17-13-31.gh-issue-101696.seJhTt.rst b/Misc/NEWS.d/next/Core and Builtins/2023-02-08-17-13-31.gh-issue-101696.seJhTt.rst
deleted file mode 100644
index ff2bbb4b564252..00000000000000
--- a/Misc/NEWS.d/next/Core and Builtins/2023-02-08-17-13-31.gh-issue-101696.seJhTt.rst
+++ /dev/null
@@ -1 +0,0 @@
-Invalidate type version tag in ``_PyStaticType_Dealloc`` for static types, avoiding bug where a false cache hit could crash the interpreter. Patch by Kumar Aditya.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-02-10-01-15-57.gh-issue-101430.T3Gegb.rst b/Misc/NEWS.d/next/Core and Builtins/2023-02-10-01-15-57.gh-issue-101430.T3Gegb.rst
deleted file mode 100644
index e617d85242144e..00000000000000
--- a/Misc/NEWS.d/next/Core and Builtins/2023-02-10-01-15-57.gh-issue-101430.T3Gegb.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Update :mod:`tracemalloc` to handle presize of object properly. Patch by
-Dong-hee Na.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-02-10-07-21-47.gh-issue-101765.MO5LlC.rst b/Misc/NEWS.d/next/Core and Builtins/2023-02-10-07-21-47.gh-issue-101765.MO5LlC.rst
deleted file mode 100644
index cc99779a944ec6..00000000000000
--- a/Misc/NEWS.d/next/Core and Builtins/2023-02-10-07-21-47.gh-issue-101765.MO5LlC.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fix SystemError / segmentation fault in iter ``__reduce__`` when internal access of ``builtins.__dict__`` keys mutates the iter object.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-02-10-15-54-57.gh-issue-87849.IUVvPz.rst b/Misc/NEWS.d/next/Core and Builtins/2023-02-10-15-54-57.gh-issue-87849.IUVvPz.rst
deleted file mode 100644
index da5f3ff79fd575..00000000000000
--- a/Misc/NEWS.d/next/Core and Builtins/2023-02-10-15-54-57.gh-issue-87849.IUVvPz.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-Change the ``SEND`` instruction to leave the receiver on the stack. This
-allows the specialized form of ``SEND`` to skip the chain of C calls and jump
-directly to the ``RESUME`` in the generator or coroutine.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-02-11-23-14-06.gh-issue-84783._P5sMa.rst b/Misc/NEWS.d/next/Core and Builtins/2023-02-11-23-14-06.gh-issue-84783._P5sMa.rst
deleted file mode 100644
index e1c851a0825a7f..00000000000000
--- a/Misc/NEWS.d/next/Core and Builtins/2023-02-11-23-14-06.gh-issue-84783._P5sMa.rst
+++ /dev/null
@@ -1 +0,0 @@
-Make the slice object hashable.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-02-12-22-40-22.gh-issue-101857._bribG.rst b/Misc/NEWS.d/next/Core and Builtins/2023-02-12-22-40-22.gh-issue-101857._bribG.rst
deleted file mode 100644
index 832cc300fa9433..00000000000000
--- a/Misc/NEWS.d/next/Core and Builtins/2023-02-12-22-40-22.gh-issue-101857._bribG.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fix xattr support detection on Linux systems by widening the check to linux, not just glibc. This fixes support for musl.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-02-13-18-21-14.gh-issue-101799.wpHbCn.rst b/Misc/NEWS.d/next/Core and Builtins/2023-02-13-18-21-14.gh-issue-101799.wpHbCn.rst
deleted file mode 100644
index 3233a573be7acd..00000000000000
--- a/Misc/NEWS.d/next/Core and Builtins/2023-02-13-18-21-14.gh-issue-101799.wpHbCn.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Add :opcode:`CALL_INTRINSIC_2` and use it instead of
-:opcode:`PREP_RERAISE_STAR`.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-02-13-22-21-58.gh-issue-74895.esMNtq.rst b/Misc/NEWS.d/next/Core and Builtins/2023-02-13-22-21-58.gh-issue-74895.esMNtq.rst
deleted file mode 100644
index adbbb601634a60..00000000000000
--- a/Misc/NEWS.d/next/Core and Builtins/2023-02-13-22-21-58.gh-issue-74895.esMNtq.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-:mod:`socket.getaddrinfo` no longer raises :class:`OverflowError` for
-:class:`int` **port** values outside of the C long range. Out of range values
-are left up to the underlying string based C library API to report. A
-:class:`socket.gaierror` ``SAI_SERVICE`` may occur instead, or no error at all
-as not all platform C libraries generate an error.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-02-16-16-57-23.gh-issue-101952.Zo1dlq.rst b/Misc/NEWS.d/next/Core and Builtins/2023-02-16-16-57-23.gh-issue-101952.Zo1dlq.rst
deleted file mode 100644
index 3902c988c8bf9f..00000000000000
--- a/Misc/NEWS.d/next/Core and Builtins/2023-02-16-16-57-23.gh-issue-101952.Zo1dlq.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fix possible segfault in ``BUILD_SET`` opcode, when new set created.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-02-16-23-19-01.gh-issue-101967.Kqr1dz.rst b/Misc/NEWS.d/next/Core and Builtins/2023-02-16-23-19-01.gh-issue-101967.Kqr1dz.rst
deleted file mode 100644
index 6e681f910f5359..00000000000000
--- a/Misc/NEWS.d/next/Core and Builtins/2023-02-16-23-19-01.gh-issue-101967.Kqr1dz.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fix possible segfault in ``positional_only_passed_as_keyword`` function, when new list created.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-02-17-10-12-13.gh-issue-100982.mJGJQw.rst b/Misc/NEWS.d/next/Core and Builtins/2023-02-17-10-12-13.gh-issue-100982.mJGJQw.rst
deleted file mode 100644
index 53bbc860c53f37..00000000000000
--- a/Misc/NEWS.d/next/Core and Builtins/2023-02-17-10-12-13.gh-issue-100982.mJGJQw.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Restrict the scope of the :opcode:`FOR_ITER_RANGE` instruction to the scope of the
-original :opcode:`FOR_ITER` instruction, to allow instrumentation.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-02-20-15-18-33.gh-issue-102056.uHKuwH.rst b/Misc/NEWS.d/next/Core and Builtins/2023-02-20-15-18-33.gh-issue-102056.uHKuwH.rst
deleted file mode 100644
index 78cd525b365fe5..00000000000000
--- a/Misc/NEWS.d/next/Core and Builtins/2023-02-20-15-18-33.gh-issue-102056.uHKuwH.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fix error handling bugs in interpreter's exception printing code, which could cause a crash on infinite recursion.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-02-22-15-15-32.gh-issue-102027.Km4G-d.rst b/Misc/NEWS.d/next/Core and Builtins/2023-02-22-15-15-32.gh-issue-102027.Km4G-d.rst
deleted file mode 100644
index 514a8ef26594dc..00000000000000
--- a/Misc/NEWS.d/next/Core and Builtins/2023-02-22-15-15-32.gh-issue-102027.Km4G-d.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Use ``GetCurrentProcessId`` on Windows when ``getpid`` is unavailable. Patch by
-Max Bachmann.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-02-24-17-59-39.gh-issue-102126.HTT8Vc.rst b/Misc/NEWS.d/next/Core and Builtins/2023-02-24-17-59-39.gh-issue-102126.HTT8Vc.rst
deleted file mode 100644
index 68c43688c3df03..00000000000000
--- a/Misc/NEWS.d/next/Core and Builtins/2023-02-24-17-59-39.gh-issue-102126.HTT8Vc.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fix deadlock at shutdown when clearing thread states if any finalizer tries to acquire the runtime head lock. Patch by Kumar Aditya.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-02-26-23-10-32.gh-issue-102250.7MUKoC.rst b/Misc/NEWS.d/next/Core and Builtins/2023-02-26-23-10-32.gh-issue-102250.7MUKoC.rst
deleted file mode 100644
index 17ab0cd4367991..00000000000000
--- a/Misc/NEWS.d/next/Core and Builtins/2023-02-26-23-10-32.gh-issue-102250.7MUKoC.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fixed a segfault occurring when the interpreter calls a ``__bool__`` method that raises.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-02-28-21-17-03.gh-issue-102336.-wL3Tm.rst b/Misc/NEWS.d/next/Core and Builtins/2023-02-28-21-17-03.gh-issue-102336.-wL3Tm.rst
deleted file mode 100644
index 0c3e4bd4b86094..00000000000000
--- a/Misc/NEWS.d/next/Core and Builtins/2023-02-28-21-17-03.gh-issue-102336.-wL3Tm.rst
+++ /dev/null
@@ -1 +0,0 @@
-Cleanup Windows 7 specific special handling. Patch by Max Bachmann.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-03-04-06-48-34.gh-issue-102397.ACJaOf.rst b/Misc/NEWS.d/next/Core and Builtins/2023-03-04-06-48-34.gh-issue-102397.ACJaOf.rst
new file mode 100644
index 00000000000000..db0b3f32c2ec0b
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2023-03-04-06-48-34.gh-issue-102397.ACJaOf.rst
@@ -0,0 +1,2 @@
+Fix segfault from race condition in signal handling during garbage collection.
+Patch by Kumar Aditya.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-03-04-20-56-12.gh-issue-102356.07KvUd.rst b/Misc/NEWS.d/next/Core and Builtins/2023-03-04-20-56-12.gh-issue-102356.07KvUd.rst
deleted file mode 100644
index c03fd5266bc301..00000000000000
--- a/Misc/NEWS.d/next/Core and Builtins/2023-03-04-20-56-12.gh-issue-102356.07KvUd.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Fix a bug that caused a crash when deallocating deeply nested filter
-objects. Patch by Marta Gómez Macías.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-03-06-13-05-33.gh-issue-102416.dz6K5f.rst b/Misc/NEWS.d/next/Core and Builtins/2023-03-06-13-05-33.gh-issue-102416.dz6K5f.rst
deleted file mode 100644
index 9ffc67cfb7ed56..00000000000000
--- a/Misc/NEWS.d/next/Core and Builtins/2023-03-06-13-05-33.gh-issue-102416.dz6K5f.rst
+++ /dev/null
@@ -1 +0,0 @@
-Do not memoize incorrectly automatically generated loop rules in the parser. Patch by Pablo Galindo.
diff --git a/Misc/NEWS.d/next/Documentation/2023-02-07-21-43-24.gh-issue-97725.cuY7Cd.rst b/Misc/NEWS.d/next/Documentation/2023-02-07-21-43-24.gh-issue-97725.cuY7Cd.rst
deleted file mode 100644
index fd9ea049c23968..00000000000000
--- a/Misc/NEWS.d/next/Documentation/2023-02-07-21-43-24.gh-issue-97725.cuY7Cd.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Fix :meth:`asyncio.Task.print_stack` description for ``file=None``.
-Patch by Oleg Iarygin.
diff --git a/Misc/NEWS.d/next/Documentation/2023-02-19-10-33-01.gh-issue-85417.kYO8u3.rst b/Misc/NEWS.d/next/Documentation/2023-02-19-10-33-01.gh-issue-85417.kYO8u3.rst
deleted file mode 100644
index a5532df14795d2..00000000000000
--- a/Misc/NEWS.d/next/Documentation/2023-02-19-10-33-01.gh-issue-85417.kYO8u3.rst
+++ /dev/null
@@ -1 +0,0 @@
-Update :mod:`cmath` documentation to clarify behaviour on branch cuts.
diff --git a/Misc/NEWS.d/next/Library/2018-06-20-09-12-21.bpo-23224.zxCQ13.rst b/Misc/NEWS.d/next/Library/2018-06-20-09-12-21.bpo-23224.zxCQ13.rst
deleted file mode 100644
index 8909753c7f9ee6..00000000000000
--- a/Misc/NEWS.d/next/Library/2018-06-20-09-12-21.bpo-23224.zxCQ13.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Fix segfaults when creating :class:`lzma.LZMADecompressor` and
-:class:`bz2.BZ2Decompressor` objects without calling ``__init__()``, and fix
-leakage of locks and internal buffers when calling the ``__init__()``
-methods of :class:`lzma.LZMADecompressor`, :class:`lzma.LZMACompressor`,
-:class:`bz2.BZ2Compressor`, and :class:`bz2.BZ2Decompressor` objects
-multiple times.
diff --git a/Misc/NEWS.d/next/Library/2022-09-05-12-17-34.gh-issue-88233.gff9qJ.rst b/Misc/NEWS.d/next/Library/2022-09-05-12-17-34.gh-issue-88233.gff9qJ.rst
deleted file mode 100644
index 806f7011edc398..00000000000000
--- a/Misc/NEWS.d/next/Library/2022-09-05-12-17-34.gh-issue-88233.gff9qJ.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Correctly preserve "extra" fields in ``zipfile`` regardless of their
-ordering relative to a zip64 "extra."
diff --git a/Misc/NEWS.d/next/Library/2022-10-22-09-26-43.gh-issue-96764.Dh9Y5L.rst b/Misc/NEWS.d/next/Library/2022-10-22-09-26-43.gh-issue-96764.Dh9Y5L.rst
deleted file mode 100644
index a0174291cbc311..00000000000000
--- a/Misc/NEWS.d/next/Library/2022-10-22-09-26-43.gh-issue-96764.Dh9Y5L.rst
+++ /dev/null
@@ -1 +0,0 @@
-:func:`asyncio.wait_for` now uses :func:`asyncio.timeout` as its underlying implementation. Patch by Kumar Aditya.
diff --git a/Misc/NEWS.d/next/Library/2023-01-02-22-41-44.gh-issue-99138.17hp9U.rst b/Misc/NEWS.d/next/Library/2023-01-02-22-41-44.gh-issue-99138.17hp9U.rst
deleted file mode 100644
index 3dd4646f40e1e5..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-01-02-22-41-44.gh-issue-99138.17hp9U.rst
+++ /dev/null
@@ -1 +0,0 @@
-Apply :pep:`687` to :mod:`zoneinfo`. Patch by Erlend E. Aasland.
diff --git a/Misc/NEWS.d/next/Library/2023-01-06-21-14-41.gh-issue-100809.I697UT.rst b/Misc/NEWS.d/next/Library/2023-01-06-21-14-41.gh-issue-100809.I697UT.rst
deleted file mode 100644
index 54082de88ccf4a..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-01-06-21-14-41.gh-issue-100809.I697UT.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-Fix handling of drive-relative paths (like 'C:' and 'C:foo') in
-:meth:`pathlib.Path.absolute`. This method now uses the OS API
-to retrieve the correct current working directory for the drive.
diff --git a/Misc/NEWS.d/next/Library/2023-01-25-00-14-52.gh-issue-101277.FceHX7.rst b/Misc/NEWS.d/next/Library/2023-01-25-00-14-52.gh-issue-101277.FceHX7.rst
deleted file mode 100644
index e09c0e09fb388f..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-01-25-00-14-52.gh-issue-101277.FceHX7.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Remove global state from :mod:`itertools` module (:pep:`687`). Patches by
-Erlend E. Aasland.
diff --git a/Misc/NEWS.d/next/Library/2023-01-27-02-53-50.gh-issue-101360.bPB7SL.rst b/Misc/NEWS.d/next/Library/2023-01-27-02-53-50.gh-issue-101360.bPB7SL.rst
deleted file mode 100644
index 4cfb136c5db853..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-01-27-02-53-50.gh-issue-101360.bPB7SL.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-Fix anchor matching in :meth:`pathlib.PureWindowsPath.match`. Path and
-pattern anchors are now matched with :mod:`fnmatch`, just like other path
-parts. This allows patterns such as ``"*:/Users/*"`` to be matched.
diff --git a/Misc/NEWS.d/next/Library/2023-02-01-10-42-16.gh-issue-63301.XNxSFh.rst b/Misc/NEWS.d/next/Library/2023-02-01-10-42-16.gh-issue-63301.XNxSFh.rst
deleted file mode 100644
index e00e71fb8554f3..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-01-10-42-16.gh-issue-63301.XNxSFh.rst
+++ /dev/null
@@ -1 +0,0 @@
-Set exit code when :mod:`tabnanny` CLI exits on error.
diff --git a/Misc/NEWS.d/next/Library/2023-02-04-16-35-46.gh-issue-101561.Xo6pIZ.rst b/Misc/NEWS.d/next/Library/2023-02-04-16-35-46.gh-issue-101561.Xo6pIZ.rst
deleted file mode 100644
index 2f6a4153062e5a..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-04-16-35-46.gh-issue-101561.Xo6pIZ.rst
+++ /dev/null
@@ -1 +0,0 @@
-Add a new decorator :func:`typing.override`. See :pep:`698` for details. Patch by Steven Troxler.
diff --git a/Misc/NEWS.d/next/Library/2023-02-05-21-40-15.gh-issue-85984.Kfzbb2.rst b/Misc/NEWS.d/next/Library/2023-02-05-21-40-15.gh-issue-85984.Kfzbb2.rst
deleted file mode 100644
index c91829f2c739af..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-05-21-40-15.gh-issue-85984.Kfzbb2.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-Refactored the implementation of :func:`pty.fork` to use :func:`os.login_tty`.
-
-A :exc:`DeprecationWarning` is now raised by ``pty.master_open()`` and ``pty.slave_open()``. They were
-undocumented and deprecated long long ago in the docstring in favor of :func:`pty.openpty`.
diff --git a/Misc/NEWS.d/next/Library/2023-02-07-20-46-08.gh-issue-101362.2ckZ6R.rst b/Misc/NEWS.d/next/Library/2023-02-07-20-46-08.gh-issue-101362.2ckZ6R.rst
deleted file mode 100644
index 8421466cdbb3c9..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-07-20-46-08.gh-issue-101362.2ckZ6R.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Speed up :class:`pathlib.Path` construction by running the path flavour
-compatibility check only when pathlib is imported.
diff --git a/Misc/NEWS.d/next/Library/2023-02-07-21-16-41.gh-issue-101362.KMQllM.rst b/Misc/NEWS.d/next/Library/2023-02-07-21-16-41.gh-issue-101362.KMQllM.rst
deleted file mode 100644
index af4ee9ad904868..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-07-21-16-41.gh-issue-101362.KMQllM.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Speed up :class:`pathlib.PurePath` construction by calling
-:func:`os.path.join` only when two or more arguments are given.
diff --git a/Misc/NEWS.d/next/Library/2023-02-07-22-20-32.gh-issue-101362.Jlk6mt.rst b/Misc/NEWS.d/next/Library/2023-02-07-22-20-32.gh-issue-101362.Jlk6mt.rst
deleted file mode 100644
index c05f92ae699de9..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-07-22-20-32.gh-issue-101362.Jlk6mt.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-Speed up :class:`pathlib.PurePath` construction by handling arguments more
-uniformly. When a :class:`pathlib.Path` argument is supplied,
-we use its string representation rather than joining its parts
-with :func:`os.path.join`.
diff --git a/Misc/NEWS.d/next/Library/2023-02-07-22-21-46.gh-issue-101446.-c0FdK.rst b/Misc/NEWS.d/next/Library/2023-02-07-22-21-46.gh-issue-101446.-c0FdK.rst
deleted file mode 100644
index ddf897b71bb1d1..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-07-22-21-46.gh-issue-101446.-c0FdK.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Change repr of :class:`collections.OrderedDict` to use regular dictionary
-formating instead of pairs of keys and values.
diff --git a/Misc/NEWS.d/next/Library/2023-02-08-18-20-58.gh-issue-101693.4_LPXj.rst b/Misc/NEWS.d/next/Library/2023-02-08-18-20-58.gh-issue-101693.4_LPXj.rst
deleted file mode 100644
index e436054b15b657..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-08-18-20-58.gh-issue-101693.4_LPXj.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-In :meth:`sqlite3.Cursor.execute`, :exc:`DeprecationWarning` is now emitted
-when :ref:`named placeholders ` are used together with
-parameters supplied as a :term:`sequence` instead of as a :class:`dict`.
-Starting from Python 3.14, using named placeholders with parameters supplied
-as a sequence will raise a :exc:`~sqlite3.ProgrammingError`.
-Patch by Erlend E. Aasland.
diff --git a/Misc/NEWS.d/next/Library/2023-02-10-11-59-13.gh-issue-101773.J_kI7y.rst b/Misc/NEWS.d/next/Library/2023-02-10-11-59-13.gh-issue-101773.J_kI7y.rst
deleted file mode 100644
index b577d93d28c2ae..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-10-11-59-13.gh-issue-101773.J_kI7y.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Optimize :class:`fractions.Fraction` for small components. The private argument
-``_normalize`` of the :class:`fractions.Fraction` constructor has been removed.
diff --git a/Misc/NEWS.d/next/Library/2023-02-10-16-02-29.gh-issue-101517.r7S2u8.rst b/Misc/NEWS.d/next/Library/2023-02-10-16-02-29.gh-issue-101517.r7S2u8.rst
deleted file mode 100644
index a5f6bdfa5ac2f0..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-10-16-02-29.gh-issue-101517.r7S2u8.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fixed bug where :mod:`bdb` looks up the source line with :mod:`linecache` with a ``lineno=None``, which causes it to fail with an unhandled exception.
diff --git a/Misc/NEWS.d/next/Library/2023-02-11-13-23-29.gh-issue-97786.QjvQ1B.rst b/Misc/NEWS.d/next/Library/2023-02-11-13-23-29.gh-issue-97786.QjvQ1B.rst
deleted file mode 100644
index df194b67590d67..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-11-13-23-29.gh-issue-97786.QjvQ1B.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Fix potential undefined behaviour in corner cases of floating-point-to-time
-conversions.
diff --git a/Misc/NEWS.d/next/Library/2023-02-13-12-55-48.gh-issue-87634.q-SBhJ.rst b/Misc/NEWS.d/next/Library/2023-02-13-12-55-48.gh-issue-87634.q-SBhJ.rst
deleted file mode 100644
index a17927500bd9a5..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-13-12-55-48.gh-issue-87634.q-SBhJ.rst
+++ /dev/null
@@ -1 +0,0 @@
-Remove locking behavior from :func:`functools.cached_property`.
diff --git a/Misc/NEWS.d/next/Library/2023-02-14-09-08-48.gh-issue-101892.FMos8l.rst b/Misc/NEWS.d/next/Library/2023-02-14-09-08-48.gh-issue-101892.FMos8l.rst
deleted file mode 100644
index d586779b3a8a36..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-14-09-08-48.gh-issue-101892.FMos8l.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-Callable iterators no longer raise :class:`SystemError` when the
-callable object exhausts the iterator but forgets to either return a
-sentinel value or raise :class:`StopIteration`.
diff --git a/Misc/NEWS.d/next/Library/2023-02-15-01-54-06.gh-issue-99108.rjTSic.rst b/Misc/NEWS.d/next/Library/2023-02-15-01-54-06.gh-issue-99108.rjTSic.rst
deleted file mode 100644
index 1612c89c0ea6be..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-15-01-54-06.gh-issue-99108.rjTSic.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-The built-in extension modules for :mod:`hashlib` SHA2 algorithms, used when
-OpenSSL does not provide them, now live in a single internal ``_sha2`` module
-instead of separate ``_sha256`` and ``_sha512`` modules.
diff --git a/Misc/NEWS.d/next/Library/2023-02-17-18-44-27.gh-issue-101997.A6_blD.rst b/Misc/NEWS.d/next/Library/2023-02-17-18-44-27.gh-issue-101997.A6_blD.rst
deleted file mode 100644
index f9dfd46d1ed430..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-17-18-44-27.gh-issue-101997.A6_blD.rst
+++ /dev/null
@@ -1 +0,0 @@
-Upgrade pip wheel bundled with ensurepip (pip 23.0.1)
diff --git a/Misc/NEWS.d/next/Library/2023-02-17-19-00-58.gh-issue-97930.C_nQjb.rst b/Misc/NEWS.d/next/Library/2023-02-17-19-00-58.gh-issue-97930.C_nQjb.rst
deleted file mode 100644
index 967e13f752bcd1..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-17-19-00-58.gh-issue-97930.C_nQjb.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-Apply changes from `importlib_resources 5.12
-`_,
-including fix for ``MultiplexedPath`` to support directories in multiple
-namespaces (python/importlib_resources#265).
diff --git a/Misc/NEWS.d/next/Library/2023-02-17-20-24-15.gh-issue-101566.FjgWBt.rst b/Misc/NEWS.d/next/Library/2023-02-17-20-24-15.gh-issue-101566.FjgWBt.rst
deleted file mode 100644
index 5fc1a0288a82dc..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-17-20-24-15.gh-issue-101566.FjgWBt.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-In zipfile, sync Path with `zipp 3.14
-`_, including
-fix for extractall on the underlying zipfile after being wrapped in
-``Path``.
diff --git a/Misc/NEWS.d/next/Library/2023-02-21-07-15-41.gh-issue-101936.QVOxHH.rst b/Misc/NEWS.d/next/Library/2023-02-21-07-15-41.gh-issue-101936.QVOxHH.rst
deleted file mode 100644
index 55841da44b1146..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-21-07-15-41.gh-issue-101936.QVOxHH.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-The default value of ``fp`` becomes :class:`io.BytesIO` if :exc:`~urllib.error.HTTPError`
-is initialized without a designated ``fp`` parameter. Patch by Long Vo.
diff --git a/Misc/NEWS.d/next/Library/2023-02-21-10-05-33.gh-issue-101961.7e56jh.rst b/Misc/NEWS.d/next/Library/2023-02-21-10-05-33.gh-issue-101961.7e56jh.rst
deleted file mode 100644
index a3d4119e7cbdce..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-21-10-05-33.gh-issue-101961.7e56jh.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-For the binary mode, :func:`fileinput.hookcompressed` doesn't set the ``encoding`` value
-even if the value is ``None``. Patch by Gihwan Kim.
diff --git a/Misc/NEWS.d/next/Library/2023-02-23-15-06-01.gh-issue-102179.P6KQ4c.rst b/Misc/NEWS.d/next/Library/2023-02-23-15-06-01.gh-issue-102179.P6KQ4c.rst
deleted file mode 100644
index f77493e267ac7e..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-23-15-06-01.gh-issue-102179.P6KQ4c.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fix :func:`os.dup2` error message for negative fds.
diff --git a/Misc/NEWS.d/next/Library/2023-02-23-20-39-52.gh-issue-81652.Vxz0Mr.rst b/Misc/NEWS.d/next/Library/2023-02-23-20-39-52.gh-issue-81652.Vxz0Mr.rst
deleted file mode 100644
index 48acce1d863ea6..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-23-20-39-52.gh-issue-81652.Vxz0Mr.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Add :data:`mmap.MAP_ALIGNED_SUPER` FreeBSD and :data:`mmap.MAP_CONCEAL`
-OpenBSD constants to :mod:`mmap`. Patch by Yeojin Kim.
diff --git a/Misc/NEWS.d/next/Library/2023-02-26-12-37-17.gh-issue-91038.S4rFH_.rst b/Misc/NEWS.d/next/Library/2023-02-26-12-37-17.gh-issue-91038.S4rFH_.rst
deleted file mode 100644
index 2667ff120fd402..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-26-12-37-17.gh-issue-91038.S4rFH_.rst
+++ /dev/null
@@ -1 +0,0 @@
-:meth:`platform.platform` now has boolean default arguments.
diff --git a/Misc/NEWS.d/next/Library/2023-02-28-09-52-25.gh-issue-101979.or3hXV.rst b/Misc/NEWS.d/next/Library/2023-02-28-09-52-25.gh-issue-101979.or3hXV.rst
deleted file mode 100644
index 1efe72439b3a4a..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-02-28-09-52-25.gh-issue-101979.or3hXV.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Fix a bug where parentheses in the ``metavar`` argument to :meth:`argparse.ArgumentParser.add_argument` were
-dropped. Patch by Yeojin Kim.
diff --git a/Misc/NEWS.d/next/Library/2023-03-04-14-46-47.gh-issue-102302.-b_s6Z.rst b/Misc/NEWS.d/next/Library/2023-03-04-14-46-47.gh-issue-102302.-b_s6Z.rst
deleted file mode 100644
index aaf4e62069ca24..00000000000000
--- a/Misc/NEWS.d/next/Library/2023-03-04-14-46-47.gh-issue-102302.-b_s6Z.rst
+++ /dev/null
@@ -1 +0,0 @@
-Micro-optimise hashing of :class:`inspect.Parameter`, reducing the time it takes to hash an instance by around 40%.
diff --git a/Misc/NEWS.d/next/Security/2023-01-24-16-12-00.gh-issue-101283.9tqu39.rst b/Misc/NEWS.d/next/Security/2023-01-24-16-12-00.gh-issue-101283.9tqu39.rst
deleted file mode 100644
index 0efdfa10234185..00000000000000
--- a/Misc/NEWS.d/next/Security/2023-01-24-16-12-00.gh-issue-101283.9tqu39.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-:class:`subprocess.Popen` now uses a safer approach to find
-``cmd.exe`` when launching with ``shell=True``. Patch by Eryk Sun,
-based on a patch by Oleg Iarygin.
diff --git a/Misc/NEWS.d/next/Security/2023-02-08-12-57-35.gh-issue-99108.6tnmhA.rst b/Misc/NEWS.d/next/Security/2023-02-08-12-57-35.gh-issue-99108.6tnmhA.rst
deleted file mode 100644
index 6a7a309dad5d8f..00000000000000
--- a/Misc/NEWS.d/next/Security/2023-02-08-12-57-35.gh-issue-99108.6tnmhA.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-Replace the builtin :mod:`hashlib` implementations of SHA2-384 and SHA2-512
-originally from LibTomCrypt with formally verified, side-channel resistant
-code from the `HACL* ~https://github.com/hacl-star/hacl-star/>`_ project.
-The builtins remain a fallback only used when OpenSSL does not provide them.
diff --git a/Misc/NEWS.d/next/Security/2023-02-08-22-03-04.gh-issue-101727.9P5eZz.rst b/Misc/NEWS.d/next/Security/2023-02-08-22-03-04.gh-issue-101727.9P5eZz.rst
deleted file mode 100644
index 43acc82063fd7a..00000000000000
--- a/Misc/NEWS.d/next/Security/2023-02-08-22-03-04.gh-issue-101727.9P5eZz.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-Updated the OpenSSL version used in Windows and macOS binary release builds
-to 1.1.1t to address CVE-2023-0286, CVE-2022-4303, and CVE-2022-4303 per
-`the OpenSSL 2023-02-07 security advisory
-`_.
diff --git a/Misc/NEWS.d/next/Security/2023-02-17-10-42-48.gh-issue-99108.MKA8-f.rst b/Misc/NEWS.d/next/Security/2023-02-17-10-42-48.gh-issue-99108.MKA8-f.rst
deleted file mode 100644
index 723d8a43a09f9e..00000000000000
--- a/Misc/NEWS.d/next/Security/2023-02-17-10-42-48.gh-issue-99108.MKA8-f.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Replace builtin hashlib implementations of MD5 and SHA1 with verified ones
-from the HACL* project.
diff --git a/Misc/NEWS.d/next/Tests/2023-02-11-20-28-08.gh-issue-89792.S-Y5BZ.rst b/Misc/NEWS.d/next/Tests/2023-02-11-20-28-08.gh-issue-89792.S-Y5BZ.rst
deleted file mode 100644
index 9de278919ef2f8..00000000000000
--- a/Misc/NEWS.d/next/Tests/2023-02-11-20-28-08.gh-issue-89792.S-Y5BZ.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-``test_tools`` now copies up to 10x less source data to a temporary directory
-during the ``freeze`` test by ignoring git metadata and other artifacts. It
-also limits its python build parallelism based on os.cpu_count instead of hard
-coding it as 8 cores.
diff --git a/Misc/NEWS.d/next/Tests/2023-02-11-22-36-10.gh-issue-85984.EVXjT9.rst b/Misc/NEWS.d/next/Tests/2023-02-11-22-36-10.gh-issue-85984.EVXjT9.rst
deleted file mode 100644
index 402f99ea6c6ebf..00000000000000
--- a/Misc/NEWS.d/next/Tests/2023-02-11-22-36-10.gh-issue-85984.EVXjT9.rst
+++ /dev/null
@@ -1 +0,0 @@
-Utilize new "winsize" functions from termios in pty tests.
diff --git a/Misc/NEWS.d/next/Tests/2023-02-18-10-51-02.gh-issue-102019.0797SJ.rst b/Misc/NEWS.d/next/Tests/2023-02-18-10-51-02.gh-issue-102019.0797SJ.rst
deleted file mode 100644
index 63e36046d26dfe..00000000000000
--- a/Misc/NEWS.d/next/Tests/2023-02-18-10-51-02.gh-issue-102019.0797SJ.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Fix deadlock on shutdown if ``test_current_{exception,frames}`` fails. Patch
-by Jacob Bower.
diff --git a/Misc/NEWS.d/next/Windows/2023-01-25-11-33-54.gh-issue-101196.wAX_2g.rst b/Misc/NEWS.d/next/Windows/2023-01-25-11-33-54.gh-issue-101196.wAX_2g.rst
deleted file mode 100644
index c61e9b90fb5373..00000000000000
--- a/Misc/NEWS.d/next/Windows/2023-01-25-11-33-54.gh-issue-101196.wAX_2g.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-The functions ``os.path.isdir``, ``os.path.isfile``, ``os.path.islink`` and
-``os.path.exists`` are now 13% to 28% faster on Windows, by making fewer Win32
-API calls.
diff --git a/Misc/NEWS.d/next/Windows/2023-02-07-18-22-54.gh-issue-101614.NjVP0n.rst b/Misc/NEWS.d/next/Windows/2023-02-07-18-22-54.gh-issue-101614.NjVP0n.rst
deleted file mode 100644
index 8ed0995d78925b..00000000000000
--- a/Misc/NEWS.d/next/Windows/2023-02-07-18-22-54.gh-issue-101614.NjVP0n.rst
+++ /dev/null
@@ -1 +0,0 @@
-Correctly handle extensions built against debug binaries that reference ``python3_d.dll``.
diff --git a/Misc/NEWS.d/next/Windows/2023-02-09-22-09-27.gh-issue-101759.zFlqSH.rst b/Misc/NEWS.d/next/Windows/2023-02-09-22-09-27.gh-issue-101759.zFlqSH.rst
deleted file mode 100644
index 62bcac34397d2e..00000000000000
--- a/Misc/NEWS.d/next/Windows/2023-02-09-22-09-27.gh-issue-101759.zFlqSH.rst
+++ /dev/null
@@ -1 +0,0 @@
-Update Windows installer to SQLite 3.40.1.
diff --git a/Misc/NEWS.d/next/Windows/2023-02-10-14-26-05.gh-issue-101763.RPaj7r.rst b/Misc/NEWS.d/next/Windows/2023-02-10-14-26-05.gh-issue-101763.RPaj7r.rst
deleted file mode 100644
index e7e5a73afeb532..00000000000000
--- a/Misc/NEWS.d/next/Windows/2023-02-10-14-26-05.gh-issue-101763.RPaj7r.rst
+++ /dev/null
@@ -1 +0,0 @@
-Updates copy of libffi bundled with Windows installs to 3.4.4.
diff --git a/Misc/NEWS.d/next/Windows/2023-02-13-16-32-50.gh-issue-101849.7lm_53.rst b/Misc/NEWS.d/next/Windows/2023-02-13-16-32-50.gh-issue-101849.7lm_53.rst
deleted file mode 100644
index 861d4de9f9a650..00000000000000
--- a/Misc/NEWS.d/next/Windows/2023-02-13-16-32-50.gh-issue-101849.7lm_53.rst
+++ /dev/null
@@ -1 +0,0 @@
-Ensures installer will correctly upgrade existing ``py.exe`` launcher installs.
diff --git a/Misc/NEWS.d/next/Windows/2023-02-13-18-05-49.gh-issue-101881._TnHzN.rst b/Misc/NEWS.d/next/Windows/2023-02-13-18-05-49.gh-issue-101881._TnHzN.rst
deleted file mode 100644
index ba58dd4f5cb450..00000000000000
--- a/Misc/NEWS.d/next/Windows/2023-02-13-18-05-49.gh-issue-101881._TnHzN.rst
+++ /dev/null
@@ -1 +0,0 @@
-Add support for the os.get_blocking() and os.set_blocking() functions on Windows.
diff --git a/Misc/NEWS.d/next/Windows/2023-02-15-11-08-10.gh-issue-101881.fScr3m.rst b/Misc/NEWS.d/next/Windows/2023-02-15-11-08-10.gh-issue-101881.fScr3m.rst
deleted file mode 100644
index 099b2c1c07a665..00000000000000
--- a/Misc/NEWS.d/next/Windows/2023-02-15-11-08-10.gh-issue-101881.fScr3m.rst
+++ /dev/null
@@ -1 +0,0 @@
-Handle read and write operations on non-blocking pipes properly on Windows.
diff --git a/Misc/NEWS.d/next/Windows/2023-03-01-01-36-39.gh-issue-102344.Dgfux4.rst b/Misc/NEWS.d/next/Windows/2023-03-01-01-36-39.gh-issue-102344.Dgfux4.rst
deleted file mode 100644
index 4804212be8182c..00000000000000
--- a/Misc/NEWS.d/next/Windows/2023-03-01-01-36-39.gh-issue-102344.Dgfux4.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Implement ``winreg.QueryValue`` using ``QueryValueEx`` and
-``winreg.SetValue`` using ``SetValueEx``. Patch by Max Bachmann.
diff --git a/Misc/NEWS.d/next/macOS/2023-02-09-22-07-17.gh-issue-101759.B0JP2H.rst b/Misc/NEWS.d/next/macOS/2023-02-09-22-07-17.gh-issue-101759.B0JP2H.rst
deleted file mode 100644
index fc53d08bffc4fd..00000000000000
--- a/Misc/NEWS.d/next/macOS/2023-02-09-22-07-17.gh-issue-101759.B0JP2H.rst
+++ /dev/null
@@ -1 +0,0 @@
-Update macOS installer to SQLite 3.40.1.
diff --git a/Modules/_testcapi/exceptions.c b/Modules/_testcapi/exceptions.c
index 43b88ccf261d98..a0575213987ffc 100644
--- a/Modules/_testcapi/exceptions.c
+++ b/Modules/_testcapi/exceptions.c
@@ -78,6 +78,20 @@ make_exception_with_doc(PyObject *self, PyObject *args, PyObject *kwargs)
return PyErr_NewExceptionWithDoc(name, doc, base, dict);
}
+static PyObject *
+exc_set_object(PyObject *self, PyObject *args)
+{
+ PyObject *exc;
+ PyObject *obj;
+
+ if (!PyArg_ParseTuple(args, "OO:exc_set_object", &exc, &obj)) {
+ return NULL;
+ }
+
+ PyErr_SetObject(exc, obj);
+ return NULL;
+}
+
static PyObject *
raise_exception(PyObject *self, PyObject *args)
{
@@ -247,6 +261,7 @@ static PyMethodDef test_methods[] = {
PyDoc_STR("fatal_error(message, release_gil=False): call Py_FatalError(message)")},
{"make_exception_with_doc", _PyCFunction_CAST(make_exception_with_doc),
METH_VARARGS | METH_KEYWORDS},
+ {"exc_set_object", exc_set_object, METH_VARARGS},
{"raise_exception", raise_exception, METH_VARARGS},
{"raise_memoryerror", raise_memoryerror, METH_NOARGS},
{"set_exc_info", test_set_exc_info, METH_VARARGS},
diff --git a/Modules/_testcapi/watchers.c b/Modules/_testcapi/watchers.c
index d9ace632768ae8..1284fdc2767b6c 100644
--- a/Modules/_testcapi/watchers.c
+++ b/Modules/_testcapi/watchers.c
@@ -317,6 +317,13 @@ noop_code_event_handler(PyCodeEvent event, PyCodeObject *co)
return 0;
}
+static int
+error_code_event_handler(PyCodeEvent event, PyCodeObject *co)
+{
+ PyErr_SetString(PyExc_RuntimeError, "boom!");
+ return -1;
+}
+
static PyObject *
add_code_watcher(PyObject *self, PyObject *which_watcher)
{
@@ -333,7 +340,11 @@ add_code_watcher(PyObject *self, PyObject *which_watcher)
num_code_object_created_events[1] = 0;
num_code_object_destroyed_events[1] = 0;
}
+ else if (which_l == 2) {
+ watcher_id = PyCode_AddWatcher(error_code_event_handler);
+ }
else {
+ PyErr_Format(PyExc_ValueError, "invalid watcher %d", which_l);
return NULL;
}
if (watcher_id < 0) {
@@ -672,7 +683,7 @@ _PyTestCapi_Init_Watchers(PyObject *mod)
PyFunction_EVENT_##event)) { \
return -1; \
}
- FOREACH_FUNC_EVENT(ADD_EVENT);
+ PY_FOREACH_FUNC_EVENT(ADD_EVENT);
#undef ADD_EVENT
return 0;
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
index cd26eca351c0ed..0e472e1ee4f9dd 100644
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -148,6 +148,10 @@ get_signal_state(PyObject *module)
static inline int
compare_handler(PyObject *func, PyObject *dfl_ign_handler)
{
+ // See /~https://github.com/python/cpython/pull/102399
+ if (func == NULL || dfl_ign_handler == NULL) {
+ return 0;
+ }
assert(PyLong_CheckExact(dfl_ign_handler));
if (!PyLong_CheckExact(func)) {
return 0;
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
index 175bd57568f8f6..65b1d258fb76af 100644
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -11,9 +11,24 @@
#include "pycore_tuple.h" // _PyTuple_ITEMS()
#include "clinic/codeobject.c.h"
+static PyObject* code_repr(PyCodeObject *co);
+
+static const char *
+code_event_name(PyCodeEvent event) {
+ switch (event) {
+ #define CASE(op) \
+ case PY_CODE_EVENT_##op: \
+ return "PY_CODE_EVENT_" #op;
+ PY_FOREACH_CODE_EVENT(CASE)
+ #undef CASE
+ }
+ Py_UNREACHABLE();
+}
+
static void
notify_code_watchers(PyCodeEvent event, PyCodeObject *co)
{
+ assert(Py_REFCNT(co) > 0);
PyInterpreterState *interp = _PyInterpreterState_GET();
assert(interp->_initialized);
uint8_t bits = interp->active_code_watchers;
@@ -25,7 +40,21 @@ notify_code_watchers(PyCodeEvent event, PyCodeObject *co)
// callback must be non-null if the watcher bit is set
assert(cb != NULL);
if (cb(event, co) < 0) {
- PyErr_WriteUnraisable((PyObject *) co);
+ // Don't risk resurrecting the object if an unraisablehook keeps
+ // a reference; pass a string as context.
+ PyObject *context = NULL;
+ PyObject *repr = code_repr(co);
+ if (repr) {
+ context = PyUnicode_FromFormat(
+ "%s watcher callback for %U",
+ code_event_name(event), repr);
+ Py_DECREF(repr);
+ }
+ if (context == NULL) {
+ context = Py_NewRef(Py_None);
+ }
+ PyErr_WriteUnraisable(context);
+ Py_DECREF(context);
}
}
i++;
@@ -1667,7 +1696,14 @@ code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount,
static void
code_dealloc(PyCodeObject *co)
{
+ assert(Py_REFCNT(co) == 0);
+ Py_SET_REFCNT(co, 1);
notify_code_watchers(PY_CODE_EVENT_DESTROY, co);
+ if (Py_REFCNT(co) > 1) {
+ Py_SET_REFCNT(co, Py_REFCNT(co) - 1);
+ return;
+ }
+ Py_SET_REFCNT(co, 0);
if (co->co_extra != NULL) {
PyInterpreterState *interp = _PyInterpreterState_GET();
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index fc658ca2f4b7f8..e3795e75e3da5e 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -2308,7 +2308,14 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value)
static void
dict_dealloc(PyDictObject *mp)
{
+ assert(Py_REFCNT(mp) == 0);
+ Py_SET_REFCNT(mp, 1);
_PyDict_NotifyEvent(PyDict_EVENT_DEALLOCATED, mp, NULL, NULL);
+ if (Py_REFCNT(mp) > 1) {
+ Py_SET_REFCNT(mp, Py_REFCNT(mp) - 1);
+ return;
+ }
+ Py_SET_REFCNT(mp, 0);
PyDictValues *values = mp->ma_values;
PyDictKeysObject *keys = mp->ma_keys;
Py_ssize_t i, n;
@@ -5732,6 +5739,18 @@ PyDict_ClearWatcher(int watcher_id)
return 0;
}
+static const char *
+dict_event_name(PyDict_WatchEvent event) {
+ switch (event) {
+ #define CASE(op) \
+ case PyDict_EVENT_##op: \
+ return "PyDict_EVENT_" #op;
+ PY_FOREACH_DICT_EVENT(CASE)
+ #undef CASE
+ }
+ Py_UNREACHABLE();
+}
+
void
_PyDict_SendEvent(int watcher_bits,
PyDict_WatchEvent event,
@@ -5744,9 +5763,18 @@ _PyDict_SendEvent(int watcher_bits,
if (watcher_bits & 1) {
PyDict_WatchCallback cb = interp->dict_state.watchers[i];
if (cb && (cb(event, (PyObject*)mp, key, value) < 0)) {
- // some dict modification paths (e.g. PyDict_Clear) can't raise, so we
- // can't propagate exceptions from dict watchers.
- PyErr_WriteUnraisable((PyObject *)mp);
+ // We don't want to resurrect the dict by potentially having an
+ // unraisablehook keep a reference to it, so we don't pass the
+ // dict as context, just an informative string message. Dict
+ // repr can call arbitrary code, so we invent a simpler version.
+ PyObject *context = PyUnicode_FromFormat(
+ "%s watcher callback for ",
+ dict_event_name(event), mp);
+ if (context == NULL) {
+ context = Py_NewRef(Py_None);
+ }
+ PyErr_WriteUnraisable(context);
+ Py_DECREF(context);
}
}
watcher_bits >>= 1;
diff --git a/Objects/funcobject.c b/Objects/funcobject.c
index 91a6b3dd40a232..99048ea41c6c80 100644
--- a/Objects/funcobject.c
+++ b/Objects/funcobject.c
@@ -8,6 +8,20 @@
#include "pycore_pyerrors.h" // _PyErr_Occurred()
#include "structmember.h" // PyMemberDef
+static PyObject* func_repr(PyFunctionObject *op);
+
+static const char *
+func_event_name(PyFunction_WatchEvent event) {
+ switch (event) {
+ #define CASE(op) \
+ case PyFunction_EVENT_##op: \
+ return "PyFunction_EVENT_" #op;
+ PY_FOREACH_FUNC_EVENT(CASE)
+ #undef CASE
+ }
+ Py_UNREACHABLE();
+}
+
static void
notify_func_watchers(PyInterpreterState *interp, PyFunction_WatchEvent event,
PyFunctionObject *func, PyObject *new_value)
@@ -21,7 +35,21 @@ notify_func_watchers(PyInterpreterState *interp, PyFunction_WatchEvent event,
// callback must be non-null if the watcher bit is set
assert(cb != NULL);
if (cb(event, func, new_value) < 0) {
- PyErr_WriteUnraisable((PyObject *) func);
+ // Don't risk resurrecting the func if an unraisablehook keeps a
+ // reference; pass a string as context.
+ PyObject *context = NULL;
+ PyObject *repr = func_repr(func);
+ if (repr != NULL) {
+ context = PyUnicode_FromFormat(
+ "%s watcher callback for %U",
+ func_event_name(event), repr);
+ Py_DECREF(repr);
+ }
+ if (context == NULL) {
+ context = Py_NewRef(Py_None);
+ }
+ PyErr_WriteUnraisable(context);
+ Py_DECREF(context);
}
}
i++;
@@ -33,6 +61,7 @@ static inline void
handle_func_event(PyFunction_WatchEvent event, PyFunctionObject *func,
PyObject *new_value)
{
+ assert(Py_REFCNT(func) > 0);
PyInterpreterState *interp = _PyInterpreterState_GET();
assert(interp->_initialized);
if (interp->active_func_watchers) {
@@ -766,7 +795,14 @@ func_clear(PyFunctionObject *op)
static void
func_dealloc(PyFunctionObject *op)
{
+ assert(Py_REFCNT(op) == 0);
+ Py_SET_REFCNT(op, 1);
handle_func_event(PyFunction_EVENT_DESTROY, op, NULL);
+ if (Py_REFCNT(op) > 1) {
+ Py_SET_REFCNT(op, Py_REFCNT(op) - 1);
+ return;
+ }
+ Py_SET_REFCNT(op, 0);
_PyObject_GC_UNTRACK(op);
if (op->func_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject *) op);
diff --git a/Objects/genobject.c b/Objects/genobject.c
index 4ab6581e12ab3a..be08a59ece6b7e 100644
--- a/Objects/genobject.c
+++ b/Objects/genobject.c
@@ -1549,7 +1549,7 @@ ag_getframe(PyAsyncGenObject *ag, void *Py_UNUSED(ignored))
static PyObject *
ag_getcode(PyGenObject *gen, void *Py_UNUSED(ignored))
{
- return _gen_getcode(gen, "ag__code");
+ return _gen_getcode(gen, "ag_code");
}
static PyGetSetDef async_gen_getsetlist[] = {
diff --git a/PC/launcher.c b/PC/launcher.c
index da566a180168c5..0776e57249c427 100644
--- a/PC/launcher.c
+++ b/PC/launcher.c
@@ -770,8 +770,7 @@ run_child(wchar_t * cmdline)
window, or fetching a message). As this launcher doesn't do this
directly, that cursor remains even after the child process does these
things. We avoid that by doing a simple post+get message.
- See http://bugs.python.org/issue17290 and
- https://bitbucket.org/vinay.sajip/pylauncher/issue/20/busy-cursor-for-a-long-time-when-running
+ See http://bugs.python.org/issue17290
*/
MSG msg;
diff --git a/PC/launcher2.c b/PC/launcher2.c
index beeb2ae46b83f0..932665387f1966 100644
--- a/PC/launcher2.c
+++ b/PC/launcher2.c
@@ -2473,8 +2473,7 @@ launchEnvironment(const SearchInfo *search, const EnvironmentInfo *launch, wchar
window, or fetching a message). As this launcher doesn't do this
directly, that cursor remains even after the child process does these
things. We avoid that by doing a simple post+get message.
- See http://bugs.python.org/issue17290 and
- https://bitbucket.org/vinay.sajip/pylauncher/issue/20/busy-cursor-for-a-long-time-when-running
+ See http://bugs.python.org/issue17290
*/
MSG msg;
diff --git a/Python/compile.c b/Python/compile.c
index 2e60a8157533ad..45c97b4f8ef0e6 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -175,19 +175,18 @@ static struct jump_target_label_ NO_LABEL = {-1};
#define IS_LABEL(L) (!SAME_LABEL((L), (NO_LABEL)))
#define NEW_JUMP_TARGET_LABEL(C, NAME) \
- jump_target_label NAME = cfg_new_label(CFG_BUILDER(C)); \
+ jump_target_label NAME = instr_sequence_new_label(INSTR_SEQUENCE(C)); \
if (!IS_LABEL(NAME)) { \
return ERROR; \
}
#define USE_LABEL(C, LBL) \
- RETURN_IF_ERROR(cfg_builder_use_label(CFG_BUILDER(C), LBL))
+ RETURN_IF_ERROR(instr_sequence_use_label(INSTR_SEQUENCE(C), (LBL).id))
-struct instr {
+struct cfg_instr {
int i_opcode;
int i_oparg;
location i_loc;
- /* The following fields should not be set by the front-end: */
struct basicblock_ *i_target; /* target block (if jump instruction) */
struct basicblock_ *i_except; /* target block when exception is raised */
};
@@ -196,7 +195,7 @@ struct instr {
#define INSTR_SET_OP1(I, OP, ARG) \
do { \
assert(HAS_ARG(OP)); \
- struct instr *_instr__ptr_ = (I); \
+ struct cfg_instr *_instr__ptr_ = (I); \
_instr__ptr_->i_opcode = (OP); \
_instr__ptr_->i_oparg = (ARG); \
} while (0);
@@ -205,7 +204,7 @@ struct instr {
#define INSTR_SET_OP0(I, OP) \
do { \
assert(!HAS_ARG(OP)); \
- struct instr *_instr__ptr_ = (I); \
+ struct cfg_instr *_instr__ptr_ = (I); \
_instr__ptr_->i_opcode = (OP); \
_instr__ptr_->i_oparg = 0; \
} while (0);
@@ -235,25 +234,25 @@ is_bit_set_in_table(const uint32_t *table, int bitindex) {
}
static inline int
-is_relative_jump(struct instr *i)
+is_relative_jump(struct cfg_instr *i)
{
return is_bit_set_in_table(_PyOpcode_RelativeJump, i->i_opcode);
}
static inline int
-is_block_push(struct instr *i)
+is_block_push(struct cfg_instr *i)
{
return IS_BLOCK_PUSH_OPCODE(i->i_opcode);
}
static inline int
-is_jump(struct instr *i)
+is_jump(struct cfg_instr *i)
{
return IS_JUMP_OPCODE(i->i_opcode);
}
static int
-instr_size(struct instr *instruction)
+instr_size(struct cfg_instr *instruction)
{
int opcode = instruction->i_opcode;
assert(!IS_PSEUDO_OPCODE(opcode));
@@ -265,7 +264,7 @@ instr_size(struct instr *instruction)
}
static void
-write_instr(_Py_CODEUNIT *codestr, struct instr *instruction, int ilen)
+write_instr(_Py_CODEUNIT *codestr, struct cfg_instr *instruction, int ilen)
{
int opcode = instruction->i_opcode;
assert(!IS_PSEUDO_OPCODE(opcode));
@@ -313,7 +312,7 @@ typedef struct basicblock_ {
/* Exception stack at start of block, used by assembler to create the exception handling table */
ExceptStack *b_exceptstack;
/* pointer to an array of instructions, initially NULL */
- struct instr *b_instr;
+ struct cfg_instr *b_instr;
/* If b_next is non-NULL, it is a pointer to the next
block reached by normal control flow. */
struct basicblock_ *b_next;
@@ -342,7 +341,7 @@ typedef struct basicblock_ {
} basicblock;
-static struct instr *
+static struct cfg_instr *
basicblock_last_instr(const basicblock *b) {
assert(b->b_iused >= 0);
if (b->b_iused > 0) {
@@ -352,21 +351,15 @@ basicblock_last_instr(const basicblock *b) {
return NULL;
}
-static inline int
-basicblock_returns(const basicblock *b) {
- struct instr *last = basicblock_last_instr(b);
- return last && (last->i_opcode == RETURN_VALUE || last->i_opcode == RETURN_CONST);
-}
-
static inline int
basicblock_exits_scope(const basicblock *b) {
- struct instr *last = basicblock_last_instr(b);
+ struct cfg_instr *last = basicblock_last_instr(b);
return last && IS_SCOPE_EXIT_OPCODE(last->i_opcode);
}
static inline int
basicblock_nofallthrough(const basicblock *b) {
- struct instr *last = basicblock_last_instr(b);
+ struct cfg_instr *last = basicblock_last_instr(b);
return (last &&
(IS_SCOPE_EXIT_OPCODE(last->i_opcode) ||
IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)));
@@ -415,10 +408,208 @@ typedef struct cfg_builder_ {
basicblock *g_curblock;
/* label for the next instruction to be placed */
jump_target_label g_current_label;
- /* next free label id */
- int g_next_free_label;
} cfg_builder;
+typedef struct {
+ int i_opcode;
+ int i_oparg;
+ location i_loc;
+} instruction;
+
+
+typedef struct instr_sequence_ {
+ instruction *s_instrs;
+ int s_allocated;
+ int s_used;
+
+ int *s_labelmap; /* label id --> instr offset */
+ int s_labelmap_size;
+ int s_next_free_label; /* next free label id */
+} instr_sequence;
+
+#define INITIAL_INSTR_SEQUENCE_SIZE 100
+#define INITIAL_INSTR_SEQUENCE_LABELS_MAP_SIZE 10
+
+/*
+ * Resize the array if index is out of range.
+ *
+ * idx: the index we want to access
+ * arr: pointer to the array
+ * alloc: pointer to the capacity of the array
+ * default_alloc: initial number of items
+ * item_size: size of each item
+ *
+ */
+static int
+ensure_array_large_enough(int idx, void **arr_, int *alloc, int default_alloc, size_t item_size)
+{
+ void *arr = *arr_;
+ if (arr == NULL) {
+ int new_alloc = default_alloc;
+ if (idx >= new_alloc) {
+ new_alloc = idx + default_alloc;
+ }
+ arr = PyObject_Calloc(new_alloc, item_size);
+ if (arr == NULL) {
+ PyErr_NoMemory();
+ return ERROR;
+ }
+ *alloc = new_alloc;
+ }
+ else if (idx >= *alloc) {
+ size_t oldsize = *alloc * item_size;
+ int new_alloc = *alloc << 1;
+ if (idx >= new_alloc) {
+ new_alloc = idx + default_alloc;
+ }
+ size_t newsize = new_alloc * item_size;
+
+ if (oldsize > (SIZE_MAX >> 1)) {
+ PyErr_NoMemory();
+ return ERROR;
+ }
+
+ assert(newsize > 0);
+ void *tmp = PyObject_Realloc(arr, newsize);
+ if (tmp == NULL) {
+ PyErr_NoMemory();
+ return ERROR;
+ }
+ *alloc = new_alloc;
+ arr = tmp;
+ memset((char *)arr + oldsize, 0, newsize - oldsize);
+ }
+
+ *arr_ = arr;
+ return SUCCESS;
+}
+
+static int
+instr_sequence_next_inst(instr_sequence *seq) {
+ assert(seq->s_instrs != NULL || seq->s_used == 0);
+
+ RETURN_IF_ERROR(
+ ensure_array_large_enough(seq->s_used + 1,
+ (void**)&seq->s_instrs,
+ &seq->s_allocated,
+ INITIAL_INSTR_SEQUENCE_SIZE,
+ sizeof(instruction)));
+ assert(seq->s_used < seq->s_allocated);
+ return seq->s_used++;
+}
+
+static jump_target_label
+instr_sequence_new_label(instr_sequence *seq)
+{
+ jump_target_label lbl = {seq->s_next_free_label++};
+ return lbl;
+}
+
+static int
+instr_sequence_use_label(instr_sequence *seq, int lbl) {
+ int old_size = seq->s_labelmap_size;
+ RETURN_IF_ERROR(
+ ensure_array_large_enough(lbl,
+ (void**)&seq->s_labelmap,
+ &seq->s_labelmap_size,
+ INITIAL_INSTR_SEQUENCE_LABELS_MAP_SIZE,
+ sizeof(int)));
+
+ for(int i = old_size; i < seq->s_labelmap_size; i++) {
+ seq->s_labelmap[i] = -111; /* something weird, for debugging */
+ }
+ seq->s_labelmap[lbl] = seq->s_used; /* label refers to the next instruction */
+ return SUCCESS;
+}
+
+static int
+instr_sequence_addop(instr_sequence *seq, int opcode, int oparg, location loc)
+{
+ assert(IS_WITHIN_OPCODE_RANGE(opcode));
+ assert(!IS_ASSEMBLER_OPCODE(opcode));
+ assert(HAS_ARG(opcode) || HAS_TARGET(opcode) || oparg == 0);
+ assert(0 <= oparg && oparg < (1 << 30));
+
+ int idx = instr_sequence_next_inst(seq);
+ RETURN_IF_ERROR(idx);
+ instruction *ci = &seq->s_instrs[idx];
+ ci->i_opcode = opcode;
+ ci->i_oparg = oparg;
+ ci->i_loc = loc;
+ return SUCCESS;
+}
+
+static int
+instr_sequence_insert_instruction(instr_sequence *seq, int pos,
+ int opcode, int oparg, location loc)
+{
+ assert(pos >= 0 && pos <= seq->s_used);
+ int last_idx = instr_sequence_next_inst(seq);
+ RETURN_IF_ERROR(last_idx);
+ for (int i=last_idx-1; i >= pos; i--) {
+ seq->s_instrs[i+1] = seq->s_instrs[i];
+ }
+ instruction *ci = &seq->s_instrs[pos];
+ ci->i_opcode = opcode;
+ ci->i_oparg = oparg;
+ ci->i_loc = loc;
+
+ /* fix the labels map */
+ for(int lbl=0; lbl < seq->s_labelmap_size; lbl++) {
+ if (seq->s_labelmap[lbl] >= pos) {
+ seq->s_labelmap[lbl]++;
+ }
+ }
+ return SUCCESS;
+}
+
+static void
+instr_sequence_fini(instr_sequence *seq) {
+ PyObject_Free(seq->s_labelmap);
+ seq->s_labelmap = NULL;
+
+ PyObject_Free(seq->s_instrs);
+ seq->s_instrs = NULL;
+}
+
+static int basicblock_addop(basicblock *b, int opcode, int oparg, location loc);
+static int cfg_builder_maybe_start_new_block(cfg_builder *g);
+
+static int
+cfg_builder_use_label(cfg_builder *g, jump_target_label lbl)
+{
+ g->g_current_label = lbl;
+ return cfg_builder_maybe_start_new_block(g);
+}
+
+static int
+cfg_builder_addop(cfg_builder *g, int opcode, int oparg, location loc)
+{
+ RETURN_IF_ERROR(cfg_builder_maybe_start_new_block(g));
+ return basicblock_addop(g->g_curblock, opcode, oparg, loc);
+}
+
+static int cfg_builder_init(cfg_builder *g);
+
+static int
+instr_sequence_to_cfg(instr_sequence *seq, cfg_builder *g) {
+ memset(g, 0, sizeof(cfg_builder));
+ RETURN_IF_ERROR(cfg_builder_init(g));
+ /* Note: there can be more than one label for the same offset */
+ for (int i = 0; i < seq->s_used; i++) {
+ for (int j=0; j < seq->s_labelmap_size; j++) {
+ if (seq->s_labelmap[j] == i) {
+ jump_target_label lbl = {j};
+ RETURN_IF_ERROR(cfg_builder_use_label(g, lbl));
+ }
+ }
+ instruction *instr = &seq->s_instrs[i];
+ RETURN_IF_ERROR(cfg_builder_addop(g, instr->i_opcode, instr->i_oparg, instr->i_loc));
+ }
+ return SUCCESS;
+}
+
+
/* The following items change on entry and exit of code blocks.
They must be saved and restored when returning to a block.
*/
@@ -445,7 +636,7 @@ struct compiler_unit {
Py_ssize_t u_posonlyargcount; /* number of positional only arguments for block */
Py_ssize_t u_kwonlyargcount; /* number of keyword only arguments for block */
- cfg_builder u_cfg_builder; /* The control flow graph */
+ instr_sequence u_instr_sequence; /* codegen output */
int u_nfblocks;
struct fblockinfo u_fblock[CO_MAXBLOCKS];
@@ -481,7 +672,7 @@ struct compiler {
PyArena *c_arena; /* pointer to memory allocation arena */
};
-#define CFG_BUILDER(C) (&((C)->u->u_cfg_builder))
+#define INSTR_SEQUENCE(C) (&((C)->u->u_instr_sequence))
typedef struct {
@@ -511,9 +702,7 @@ typedef struct {
static int basicblock_next_instr(basicblock *);
-static basicblock *cfg_builder_new_block(cfg_builder *g);
-static int cfg_builder_maybe_start_new_block(cfg_builder *g);
-static int cfg_builder_addop_i(cfg_builder *g, int opcode, Py_ssize_t oparg, location loc);
+static int codegen_addop_i(instr_sequence *seq, int opcode, Py_ssize_t oparg, location loc);
static void compiler_free(struct compiler *);
static int compiler_error(struct compiler *, location loc, const char *, ...);
@@ -744,7 +933,8 @@ dictbytype(PyObject *src, int scope_type, int flag, Py_ssize_t offset)
return dest;
}
-static void
+#ifndef NDEBUG
+static bool
cfg_builder_check(cfg_builder *g)
{
for (basicblock *block = g->g_block_list; block != NULL; block = block->b_list) {
@@ -759,7 +949,11 @@ cfg_builder_check(cfg_builder *g)
assert (block->b_ialloc == 0);
}
}
+ return true;
}
+#endif
+
+static basicblock *cfg_builder_new_block(cfg_builder *g);
static int
cfg_builder_init(cfg_builder *g)
@@ -777,7 +971,7 @@ cfg_builder_init(cfg_builder *g)
static void
cfg_builder_fini(cfg_builder* g)
{
- cfg_builder_check(g);
+ assert(cfg_builder_check(g));
basicblock *b = g->g_block_list;
while (b != NULL) {
if (b->b_instr) {
@@ -792,7 +986,7 @@ cfg_builder_fini(cfg_builder* g)
static void
compiler_unit_free(struct compiler_unit *u)
{
- cfg_builder_fini(&u->u_cfg_builder);
+ instr_sequence_fini(&u->u_instr_sequence);
Py_CLEAR(u->u_ste);
Py_CLEAR(u->u_name);
Py_CLEAR(u->u_qualname);
@@ -878,13 +1072,6 @@ compiler_set_qualname(struct compiler *c)
return SUCCESS;
}
-static jump_target_label
-cfg_new_label(cfg_builder *g)
-{
- jump_target_label lbl = {g->g_next_free_label++};
- return lbl;
-}
-
/* Allocate a new block and return a pointer to it.
Returns NULL on error.
*/
@@ -912,13 +1099,6 @@ cfg_builder_use_next_block(cfg_builder *g, basicblock *block)
return block;
}
-static int
-cfg_builder_use_label(cfg_builder *g, jump_target_label lbl)
-{
- g->g_current_label = lbl;
- return cfg_builder_maybe_start_new_block(g);
-}
-
static inline int
basicblock_append_instructions(basicblock *target, basicblock *source)
{
@@ -958,40 +1138,15 @@ static int
basicblock_next_instr(basicblock *b)
{
assert(b != NULL);
- if (b->b_instr == NULL) {
- b->b_instr = (struct instr *)PyObject_Calloc(
- DEFAULT_BLOCK_SIZE, sizeof(struct instr));
- if (b->b_instr == NULL) {
- PyErr_NoMemory();
- return ERROR;
- }
- b->b_ialloc = DEFAULT_BLOCK_SIZE;
- }
- else if (b->b_iused == b->b_ialloc) {
- struct instr *tmp;
- size_t oldsize, newsize;
- oldsize = b->b_ialloc * sizeof(struct instr);
- newsize = oldsize << 1;
- if (oldsize > (SIZE_MAX >> 1)) {
- PyErr_NoMemory();
- return ERROR;
- }
+ RETURN_IF_ERROR(
+ ensure_array_large_enough(
+ b->b_iused + 1,
+ (void**)&b->b_instr,
+ &b->b_ialloc,
+ DEFAULT_BLOCK_SIZE,
+ sizeof(struct cfg_instr)));
- if (newsize == 0) {
- PyErr_NoMemory();
- return ERROR;
- }
- b->b_ialloc <<= 1;
- tmp = (struct instr *)PyObject_Realloc(
- (void *)b->b_instr, newsize);
- if (tmp == NULL) {
- PyErr_NoMemory();
- return ERROR;
- }
- b->b_instr = tmp;
- memset((char *)b->b_instr + oldsize, 0, newsize - oldsize);
- }
return b->b_iused++;
}
@@ -1100,7 +1255,7 @@ basicblock_addop(basicblock *b, int opcode, int oparg, location loc)
if (off < 0) {
return ERROR;
}
- struct instr *i = &b->b_instr[off];
+ struct cfg_instr *i = &b->b_instr[off];
i->i_opcode = opcode;
i->i_oparg = oparg;
i->i_target = NULL;
@@ -1115,7 +1270,7 @@ cfg_builder_current_block_is_terminated(cfg_builder *g)
if (IS_LABEL(g->g_current_label)) {
return true;
}
- struct instr *last = basicblock_last_instr(g->g_curblock);
+ struct cfg_instr *last = basicblock_last_instr(g->g_curblock);
return last && IS_TERMINATOR_OPCODE(last->i_opcode);
}
@@ -1135,17 +1290,10 @@ cfg_builder_maybe_start_new_block(cfg_builder *g)
}
static int
-cfg_builder_addop(cfg_builder *g, int opcode, int oparg, location loc)
-{
- RETURN_IF_ERROR(cfg_builder_maybe_start_new_block(g));
- return basicblock_addop(g->g_curblock, opcode, oparg, loc);
-}
-
-static int
-cfg_builder_addop_noarg(cfg_builder *g, int opcode, location loc)
+codegen_addop_noarg(instr_sequence *seq, int opcode, location loc)
{
assert(!HAS_ARG(opcode));
- return cfg_builder_addop(g, opcode, 0, loc);
+ return instr_sequence_addop(seq, opcode, 0, loc);
}
static Py_ssize_t
@@ -1303,7 +1451,7 @@ compiler_addop_load_const(struct compiler *c, location loc, PyObject *o)
if (arg < 0) {
return ERROR;
}
- return cfg_builder_addop_i(CFG_BUILDER(c), LOAD_CONST, arg, loc);
+ return codegen_addop_i(INSTR_SEQUENCE(c), LOAD_CONST, arg, loc);
}
static int
@@ -1314,7 +1462,7 @@ compiler_addop_o(struct compiler *c, location loc,
if (arg < 0) {
return ERROR;
}
- return cfg_builder_addop_i(CFG_BUILDER(c), opcode, arg, loc);
+ return codegen_addop_i(INSTR_SEQUENCE(c), opcode, arg, loc);
}
static int
@@ -1340,12 +1488,12 @@ compiler_addop_name(struct compiler *c, location loc,
arg <<= 1;
arg |= 1;
}
- return cfg_builder_addop_i(CFG_BUILDER(c), opcode, arg, loc);
+ return codegen_addop_i(INSTR_SEQUENCE(c), opcode, arg, loc);
}
/* Add an opcode with an integer argument */
static int
-cfg_builder_addop_i(cfg_builder *g, int opcode, Py_ssize_t oparg, location loc)
+codegen_addop_i(instr_sequence *seq, int opcode, Py_ssize_t oparg, location loc)
{
/* oparg value is unsigned, but a signed C int is usually used to store
it in the C code (like Python/ceval.c).
@@ -1356,23 +1504,23 @@ cfg_builder_addop_i(cfg_builder *g, int opcode, Py_ssize_t oparg, location loc)
EXTENDED_ARG is used for 16, 24, and 32-bit arguments. */
int oparg_ = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int);
- return cfg_builder_addop(g, opcode, oparg_, loc);
+ return instr_sequence_addop(seq, opcode, oparg_, loc);
}
static int
-cfg_builder_addop_j(cfg_builder *g, location loc,
+codegen_addop_j(instr_sequence *seq, location loc,
int opcode, jump_target_label target)
{
assert(IS_LABEL(target));
assert(IS_JUMP_OPCODE(opcode) || IS_BLOCK_PUSH_OPCODE(opcode));
- return cfg_builder_addop(g, opcode, target.id, loc);
+ return instr_sequence_addop(seq, opcode, target.id, loc);
}
#define ADDOP(C, LOC, OP) \
- RETURN_IF_ERROR(cfg_builder_addop_noarg(CFG_BUILDER(C), (OP), (LOC)))
+ RETURN_IF_ERROR(codegen_addop_noarg(INSTR_SEQUENCE(C), (OP), (LOC)))
#define ADDOP_IN_SCOPE(C, LOC, OP) { \
- if (cfg_builder_addop_noarg(CFG_BUILDER(C), (OP), (LOC)) < 0) { \
+ if (codegen_addop_noarg(INSTR_SEQUENCE(C), (OP), (LOC)) < 0) { \
compiler_exit_scope(C); \
return ERROR; \
} \
@@ -1407,10 +1555,10 @@ cfg_builder_addop_j(cfg_builder *g, location loc,
RETURN_IF_ERROR(compiler_addop_name((C), (LOC), (OP), (C)->u->u_ ## TYPE, (O)))
#define ADDOP_I(C, LOC, OP, O) \
- RETURN_IF_ERROR(cfg_builder_addop_i(CFG_BUILDER(C), (OP), (O), (LOC)))
+ RETURN_IF_ERROR(codegen_addop_i(INSTR_SEQUENCE(C), (OP), (O), (LOC)))
#define ADDOP_JUMP(C, LOC, OP, O) \
- RETURN_IF_ERROR(cfg_builder_addop_j(CFG_BUILDER(C), (LOC), (OP), (O)))
+ RETURN_IF_ERROR(codegen_addop_j(INSTR_SEQUENCE(C), (LOC), (OP), (O)))
#define ADDOP_COMPARE(C, LOC, CMP) \
RETURN_IF_ERROR(compiler_addcompare((C), (LOC), (cmpop_ty)(CMP)))
@@ -1546,9 +1694,6 @@ compiler_enter_scope(struct compiler *c, identifier name,
c->c_nestlevel++;
- cfg_builder *g = CFG_BUILDER(c);
- RETURN_IF_ERROR(cfg_builder_init(g));
-
if (u->u_scope_type == COMPILER_SCOPE_MODULE) {
loc.lineno = 0;
}
@@ -1582,7 +1727,6 @@ compiler_exit_scope(struct compiler *c)
_PyErr_WriteUnraisableMsg("on removing the last compiler "
"stack item", NULL);
}
- cfg_builder_check(CFG_BUILDER(c));
}
else {
c->u = NULL;
@@ -2321,7 +2465,7 @@ compiler_check_debug_args(struct compiler *c, arguments_ty args)
}
static inline int
-insert_instruction(basicblock *block, int pos, struct instr *instr) {
+insert_instruction(basicblock *block, int pos, struct cfg_instr *instr) {
RETURN_IF_ERROR(basicblock_next_instr(block));
for (int i = block->b_iused - 1; i > pos; i--) {
block->b_instr[i] = block->b_instr[i-1];
@@ -2336,14 +2480,10 @@ wrap_in_stopiteration_handler(struct compiler *c)
NEW_JUMP_TARGET_LABEL(c, handler);
/* Insert SETUP_CLEANUP at start */
- struct instr setup = {
- .i_opcode = SETUP_CLEANUP,
- .i_oparg = handler.id,
- .i_loc = NO_LOCATION,
- .i_target = NULL,
- };
RETURN_IF_ERROR(
- insert_instruction(c->u->u_cfg_builder.g_entryblock, 0, &setup));
+ instr_sequence_insert_instruction(
+ INSTR_SEQUENCE(c), 0,
+ SETUP_CLEANUP, handler.id, NO_LOCATION));
ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
ADDOP(c, NO_LOCATION, RETURN_VALUE);
@@ -4032,7 +4172,7 @@ compiler_nameop(struct compiler *c, location loc,
if (op == LOAD_GLOBAL) {
arg <<= 1;
}
- return cfg_builder_addop_i(CFG_BUILDER(c), op, arg, loc);
+ return codegen_addop_i(INSTR_SEQUENCE(c), op, arg, loc);
}
static int
@@ -6051,7 +6191,7 @@ emit_and_reset_fail_pop(struct compiler *c, location loc,
}
while (--pc->fail_pop_size) {
USE_LABEL(c, pc->fail_pop[pc->fail_pop_size]);
- if (cfg_builder_addop_noarg(CFG_BUILDER(c), POP_TOP, loc) < 0) {
+ if (codegen_addop_noarg(INSTR_SEQUENCE(c), POP_TOP, loc) < 0) {
pc->fail_pop_size = 0;
PyObject_Free(pc->fail_pop);
pc->fail_pop = NULL;
@@ -6491,7 +6631,7 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc)
pc->fail_pop = NULL;
pc->fail_pop_size = 0;
pc->on_top = 0;
- if (cfg_builder_addop_i(CFG_BUILDER(c), COPY, 1, LOC(alt)) < 0 ||
+ if (codegen_addop_i(INSTR_SEQUENCE(c), COPY, 1, LOC(alt)) < 0 ||
compiler_pattern(c, alt, pc) < 0) {
goto error;
}
@@ -6554,7 +6694,7 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc)
}
}
assert(control);
- if (cfg_builder_addop_j(CFG_BUILDER(c), LOC(alt), JUMP, end) < 0 ||
+ if (codegen_addop_j(INSTR_SEQUENCE(c), LOC(alt), JUMP, end) < 0 ||
emit_and_reset_fail_pop(c, LOC(alt), pc) < 0)
{
goto error;
@@ -6566,7 +6706,7 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc)
// Need to NULL this for the PyObject_Free call in the error block.
old_pc.fail_pop = NULL;
// No match. Pop the remaining copy of the subject and fail:
- if (cfg_builder_addop_noarg(CFG_BUILDER(c), POP_TOP, LOC(p)) < 0 ||
+ if (codegen_addop_noarg(INSTR_SEQUENCE(c), POP_TOP, LOC(p)) < 0 ||
jump_to_fail_pop(c, LOC(p), pc, JUMP) < 0) {
goto error;
}
@@ -6884,7 +7024,7 @@ stackdepth(basicblock *entryblock, int code_flags)
assert(depth >= 0);
basicblock *next = b->b_next;
for (int i = 0; i < b->b_iused; i++) {
- struct instr *instr = &b->b_instr[i];
+ struct cfg_instr *instr = &b->b_instr[i];
int effect = stack_effect(instr->i_opcode, instr->i_oparg, 0);
if (effect == PY_INVALID_STACK_EFFECT) {
PyErr_Format(PyExc_SystemError,
@@ -6973,7 +7113,7 @@ blocksize(basicblock *b)
}
static basicblock *
-push_except_block(ExceptStack *stack, struct instr *setup) {
+push_except_block(ExceptStack *stack, struct cfg_instr *setup) {
assert(is_block_push(setup));
int opcode = setup->i_opcode;
basicblock * target = setup->i_target;
@@ -7045,7 +7185,7 @@ label_exception_targets(basicblock *entryblock) {
b->b_exceptstack = NULL;
handler = except_stack_top(except_stack);
for (int i = 0; i < b->b_iused; i++) {
- struct instr *instr = &b->b_instr[i];
+ struct cfg_instr *instr = &b->b_instr[i];
if (is_block_push(instr)) {
if (!instr->i_target->b_visited) {
ExceptStack *copy = copy_except_stack(except_stack);
@@ -7123,7 +7263,7 @@ mark_except_handlers(basicblock *entryblock) {
#endif
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
for (int i=0; i < b->b_iused; i++) {
- struct instr *instr = &b->b_instr[i];
+ struct cfg_instr *instr = &b->b_instr[i];
if (is_block_push(instr)) {
instr->i_target->b_except_handler = 1;
}
@@ -7152,7 +7292,7 @@ mark_warm(basicblock *entryblock) {
next->b_visited = 1;
}
for (int i=0; i < b->b_iused; i++) {
- struct instr *instr = &b->b_instr[i];
+ struct cfg_instr *instr = &b->b_instr[i];
if (is_jump(instr) && !instr->i_target->b_visited) {
*sp++ = instr->i_target;
instr->i_target->b_visited = 1;
@@ -7197,7 +7337,7 @@ mark_cold(basicblock *entryblock) {
}
}
for (int i = 0; i < b->b_iused; i++) {
- struct instr *instr = &b->b_instr[i];
+ struct cfg_instr *instr = &b->b_instr[i];
if (is_jump(instr)) {
assert(i == b->b_iused - 1);
basicblock *target = b->b_instr[i].i_target;
@@ -7238,7 +7378,7 @@ push_cold_blocks_to_end(cfg_builder *g, int code_flags) {
b->b_next = explicit_jump;
/* set target */
- struct instr *last = basicblock_last_instr(explicit_jump);
+ struct cfg_instr *last = basicblock_last_instr(explicit_jump);
last->i_target = explicit_jump->b_next;
}
}
@@ -7293,7 +7433,7 @@ static void
convert_exception_handlers_to_nops(basicblock *entryblock) {
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
for (int i = 0; i < b->b_iused; i++) {
- struct instr *instr = &b->b_instr[i];
+ struct cfg_instr *instr = &b->b_instr[i];
if (is_block_push(instr) || instr->i_opcode == POP_BLOCK) {
INSTR_SET_OP0(instr, NOP);
}
@@ -7372,7 +7512,7 @@ assemble_exception_table(struct assembler *a, basicblock *entryblock)
for (b = entryblock; b != NULL; b = b->b_next) {
ioffset = b->b_offset;
for (int i = 0; i < b->b_iused; i++) {
- struct instr *instr = &b->b_instr[i];
+ struct cfg_instr *instr = &b->b_instr[i];
if (instr->i_except != handler) {
if (handler != NULL) {
RETURN_IF_ERROR(
@@ -7542,7 +7682,7 @@ assemble_emit_location(struct assembler* a, location loc, int isize)
*/
static int
-assemble_emit(struct assembler *a, struct instr *i)
+assemble_emit(struct assembler *a, struct cfg_instr *i)
{
Py_ssize_t len = PyBytes_GET_SIZE(a->a_bytecode);
_Py_CODEUNIT *code;
@@ -7562,7 +7702,7 @@ assemble_emit(struct assembler *a, struct instr *i)
static int
normalize_jumps_in_block(cfg_builder *g, basicblock *b) {
- struct instr *last = basicblock_last_instr(b);
+ struct cfg_instr *last = basicblock_last_instr(b);
if (last == NULL || !is_jump(last)) {
return SUCCESS;
}
@@ -7663,7 +7803,7 @@ assemble_jump_offsets(basicblock *entryblock)
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
bsize = b->b_offset;
for (int i = 0; i < b->b_iused; i++) {
- struct instr *instr = &b->b_instr[i];
+ struct cfg_instr *instr = &b->b_instr[i];
int isize = instr_size(instr);
/* Relative jumps are computed relative to
the instruction pointer after fetching
@@ -7735,7 +7875,7 @@ scan_block_for_locals(basicblock *b, basicblock ***sp)
// bit i is set if local i is potentially uninitialized
uint64_t unsafe_mask = b->b_unsafe_locals_mask;
for (int i = 0; i < b->b_iused; i++) {
- struct instr *instr = &b->b_instr[i];
+ struct cfg_instr *instr = &b->b_instr[i];
assert(instr->i_opcode != EXTENDED_ARG);
assert(!IS_SUPERINSTRUCTION_OPCODE(instr->i_opcode));
if (instr->i_except != NULL) {
@@ -7768,7 +7908,7 @@ scan_block_for_locals(basicblock *b, basicblock ***sp)
if (b->b_next && BB_HAS_FALLTHROUGH(b)) {
maybe_push(b->b_next, unsafe_mask, sp);
}
- struct instr *last = basicblock_last_instr(b);
+ struct cfg_instr *last = basicblock_last_instr(b);
if (last && is_jump(last)) {
assert(last->i_target != NULL);
maybe_push(last->i_target, unsafe_mask, sp);
@@ -7791,7 +7931,7 @@ fast_scan_many_locals(basicblock *entryblock, int nlocals)
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
blocknum++;
for (int i = 0; i < b->b_iused; i++) {
- struct instr *instr = &b->b_instr[i];
+ struct cfg_instr *instr = &b->b_instr[i];
assert(instr->i_opcode != EXTENDED_ARG);
assert(!IS_SUPERINSTRUCTION_OPCODE(instr->i_opcode));
int arg = instr->i_oparg;
@@ -8035,7 +8175,6 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist,
PyObject *consts = NULL;
PyObject *localsplusnames = NULL;
PyObject *localspluskinds = NULL;
-
names = dict_keys_inorder(c->u->u_names, 0);
if (!names) {
goto error;
@@ -8121,7 +8260,7 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist,
/* For debugging purposes only */
#if 0
static void
-dump_instr(struct instr *i)
+dump_instr(struct cfg_instr *i)
{
const char *jrel = (is_relative_jump(i)) ? "jrel " : "";
const char *jabs = (is_jump(i) && !is_relative_jump(i))? "jabs " : "";
@@ -8139,6 +8278,12 @@ dump_instr(struct instr *i)
i->i_loc.lineno, i->i_opcode, arg, jabs, jrel);
}
+static inline int
+basicblock_returns(const basicblock *b) {
+ struct cfg_instr *last = basicblock_last_instr(b);
+ return last && (last->i_opcode == RETURN_VALUE || last->i_opcode == RETURN_CONST);
+}
+
static void
dump_basicblock(const basicblock *b)
{
@@ -8211,14 +8356,14 @@ insert_prefix_instructions(struct compiler *c, basicblock *entryblock,
/* Add the generator prefix instructions. */
if (code_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) {
- struct instr make_gen = {
+ struct cfg_instr make_gen = {
.i_opcode = RETURN_GENERATOR,
.i_oparg = 0,
.i_loc = LOCATION(c->u->u_firstlineno, c->u->u_firstlineno, -1, -1),
.i_target = NULL,
};
RETURN_IF_ERROR(insert_instruction(entryblock, 0, &make_gen));
- struct instr pop_top = {
+ struct cfg_instr pop_top = {
.i_opcode = POP_TOP,
.i_oparg = 0,
.i_loc = NO_LOCATION,
@@ -8247,7 +8392,7 @@ insert_prefix_instructions(struct compiler *c, basicblock *entryblock,
if (oldindex == -1) {
continue;
}
- struct instr make_cell = {
+ struct cfg_instr make_cell = {
.i_opcode = MAKE_CELL,
// This will get fixed in offset_derefs().
.i_oparg = oldindex,
@@ -8261,7 +8406,7 @@ insert_prefix_instructions(struct compiler *c, basicblock *entryblock,
}
if (nfreevars) {
- struct instr copy_frees = {
+ struct cfg_instr copy_frees = {
.i_opcode = COPY_FREE_VARS,
.i_oparg = nfreevars,
.i_loc = NO_LOCATION,
@@ -8282,7 +8427,7 @@ guarantee_lineno_for_exits(basicblock *entryblock, int firstlineno) {
int lineno = firstlineno;
assert(lineno > 0);
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
- struct instr *last = basicblock_last_instr(b);
+ struct cfg_instr *last = basicblock_last_instr(b);
if (last == NULL) {
continue;
}
@@ -8324,7 +8469,7 @@ fix_cell_offsets(struct compiler *c, basicblock *entryblock, int *fixedmap)
// Then update offsets, either relative to locals or by cell2arg.
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
for (int i = 0; i < b->b_iused; i++) {
- struct instr *inst = &b->b_instr[i];
+ struct cfg_instr *inst = &b->b_instr[i];
// This is called before extended args are generated.
assert(inst->i_opcode != EXTENDED_ARG);
int oldoffset = inst->i_oparg;
@@ -8364,7 +8509,7 @@ no_redundant_nops(cfg_builder *g) {
static bool
no_redundant_jumps(cfg_builder *g) {
for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
- struct instr *last = basicblock_last_instr(b);
+ struct cfg_instr *last = basicblock_last_instr(b);
if (last != NULL) {
if (IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) {
assert(last->i_target != b->b_next);
@@ -8382,7 +8527,7 @@ opcode_metadata_is_sane(cfg_builder *g) {
bool result = true;
for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
for (int i = 0; i < b->b_iused; i++) {
- struct instr *instr = &b->b_instr[i];
+ struct cfg_instr *instr = &b->b_instr[i];
int opcode = instr->i_opcode;
int oparg = instr->i_oparg;
assert(opcode <= MAX_REAL_OPCODE);
@@ -8426,7 +8571,7 @@ remove_redundant_jumps(cfg_builder *g) {
*/
assert(no_empty_basic_blocks(g));
for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
- struct instr *last = basicblock_last_instr(b);
+ struct cfg_instr *last = basicblock_last_instr(b);
assert(last != NULL);
assert(!IS_ASSEMBLER_OPCODE(last->i_opcode));
if (IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) {
@@ -8444,7 +8589,7 @@ remove_redundant_jumps(cfg_builder *g) {
}
static int
-prepare_localsplus(struct compiler* c, int code_flags)
+prepare_localsplus(struct compiler* c, cfg_builder *g, int code_flags)
{
assert(PyDict_GET_SIZE(c->u->u_varnames) < INT_MAX);
assert(PyDict_GET_SIZE(c->u->u_cellvars) < INT_MAX);
@@ -8460,7 +8605,6 @@ prepare_localsplus(struct compiler* c, int code_flags)
return ERROR;
}
- cfg_builder* g = CFG_BUILDER(c);
// This must be called before fix_cell_offsets().
if (insert_prefix_instructions(c, g->g_entryblock, cellfixedoffsets, nfreevars, code_flags)) {
@@ -8474,20 +8618,21 @@ prepare_localsplus(struct compiler* c, int code_flags)
if (numdropped < 0) {
return ERROR;
}
+
nlocalsplus -= numdropped;
return nlocalsplus;
}
static int
-add_return_at_end_of_block(struct compiler *c, int addNone)
+add_return_at_end(struct compiler *c, int addNone)
{
- /* Make sure every block that falls off the end returns None. */
- if (!basicblock_returns(CFG_BUILDER(c)->g_curblock)) {
- if (addNone) {
- ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
- }
- ADDOP(c, NO_LOCATION, RETURN_VALUE);
+ /* Make sure every instruction stream that falls off the end returns None.
+ * This also ensures that no jump target offsets are out of bounds.
+ */
+ if (addNone) {
+ ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
}
+ ADDOP(c, NO_LOCATION, RETURN_VALUE);
return SUCCESS;
}
@@ -8496,6 +8641,8 @@ assemble(struct compiler *c, int addNone)
{
PyCodeObject *co = NULL;
PyObject *consts = NULL;
+ cfg_builder g_;
+ cfg_builder *g = &g_;
struct assembler a;
memset(&a, 0, sizeof(struct assembler));
@@ -8504,12 +8651,18 @@ assemble(struct compiler *c, int addNone)
return NULL;
}
- if (add_return_at_end_of_block(c, addNone) < 0) {
+ if (add_return_at_end(c, addNone) < 0) {
return NULL;
}
+ /** Preprocessing **/
+ if (instr_sequence_to_cfg(INSTR_SEQUENCE(c), g) < 0) {
+ goto error;
+ }
+ assert(cfg_builder_check(g));
+
int nblocks = 0;
- for (basicblock *b = CFG_BUILDER(c)->g_block_list; b != NULL; b = b->b_list) {
+ for (basicblock *b = g->g_block_list; b != NULL; b = b->b_list) {
nblocks++;
}
if ((size_t)nblocks > SIZE_MAX / sizeof(basicblock *)) {
@@ -8517,9 +8670,6 @@ assemble(struct compiler *c, int addNone)
goto error;
}
- cfg_builder *g = CFG_BUILDER(c);
- assert(g->g_entryblock != NULL);
-
/* Set firstlineno if it wasn't explicitly set. */
if (!c->u->u_firstlineno) {
if (g->g_entryblock->b_instr && g->g_entryblock->b_instr->i_loc.lineno) {
@@ -8530,9 +8680,8 @@ assemble(struct compiler *c, int addNone)
}
}
- /** Preprocessing **/
/* Map labels to targets and mark exception handlers */
- if (translate_jump_labels_to_targets(g->g_entryblock)) {
+ if (translate_jump_labels_to_targets(g->g_entryblock) < 0) {
goto error;
}
if (mark_except_handlers(g->g_entryblock) < 0) {
@@ -8550,10 +8699,10 @@ assemble(struct compiler *c, int addNone)
if (optimize_cfg(g, consts, c->c_const_cache)) {
goto error;
}
- if (add_checks_for_loads_of_uninitialized_variables(g->g_entryblock, c) < 0) {
+ if (remove_unused_consts(g->g_entryblock, consts) < 0) {
goto error;
}
- if (remove_unused_consts(g->g_entryblock, consts) < 0) {
+ if (add_checks_for_loads_of_uninitialized_variables(g->g_entryblock, c) < 0) {
goto error;
}
@@ -8570,7 +8719,7 @@ assemble(struct compiler *c, int addNone)
/** Assembly **/
- int nlocalsplus = prepare_localsplus(c, code_flags);
+ int nlocalsplus = prepare_localsplus(c, g, code_flags);
if (nlocalsplus < 0) {
goto error;
}
@@ -8587,7 +8736,6 @@ assemble(struct compiler *c, int addNone)
if (normalize_jumps(g) < 0) {
goto error;
}
-
assert(no_redundant_jumps(g));
assert(opcode_metadata_is_sane(g));
@@ -8655,6 +8803,7 @@ assemble(struct compiler *c, int addNone)
co = makecode(c, &a, consts, maxdepth, nlocalsplus, code_flags);
error:
Py_XDECREF(consts);
+ cfg_builder_fini(g);
assemble_free(&a);
return co;
}
@@ -8684,7 +8833,7 @@ get_const_value(int opcode, int oparg, PyObject *co_consts)
*/
static int
fold_tuple_on_constants(PyObject *const_cache,
- struct instr *inst,
+ struct cfg_instr *inst,
int n, PyObject *consts)
{
/* Pre-conditions */
@@ -8753,7 +8902,7 @@ swaptimize(basicblock *block, int *ix)
// NOTE: "./python -m test test_patma" serves as a good, quick stress test
// for this function. Make sure to blow away cached *.pyc files first!
assert(*ix < block->b_iused);
- struct instr *instructions = &block->b_instr[*ix];
+ struct cfg_instr *instructions = &block->b_instr[*ix];
// Find the length of the current sequence of SWAPs and NOPs, and record the
// maximum depth of the stack manipulations:
assert(instructions[0].i_opcode == SWAP);
@@ -8854,7 +9003,7 @@ static int
next_swappable_instruction(basicblock *block, int i, int lineno)
{
while (++i < block->b_iused) {
- struct instr *instruction = &block->b_instr[i];
+ struct cfg_instr *instruction = &block->b_instr[i];
if (0 <= lineno && instruction->i_loc.lineno != lineno) {
// Optimizing across this instruction could cause user-visible
// changes in the names bound between line tracing events!
@@ -8880,7 +9029,7 @@ apply_static_swaps(basicblock *block, int i)
// SWAPs are to our left, and potential swaperands are to our right:
for (; 0 <= i; i--) {
assert(i < block->b_iused);
- struct instr *swap = &block->b_instr[i];
+ struct cfg_instr *swap = &block->b_instr[i];
if (swap->i_opcode != SWAP) {
if (swap->i_opcode == NOP || SWAPPABLE(swap->i_opcode)) {
// Nope, but we know how to handle these. Keep looking:
@@ -8903,7 +9052,7 @@ apply_static_swaps(basicblock *block, int i)
}
// Success!
INSTR_SET_OP0(swap, NOP);
- struct instr temp = block->b_instr[j];
+ struct cfg_instr temp = block->b_instr[j];
block->b_instr[j] = block->b_instr[k];
block->b_instr[k] = temp;
}
@@ -8913,7 +9062,7 @@ apply_static_swaps(basicblock *block, int i)
// target->i_target using the provided opcode. Return whether or not the
// optimization was successful.
static bool
-jump_thread(struct instr *inst, struct instr *target, int opcode)
+jump_thread(struct cfg_instr *inst, struct cfg_instr *target, int opcode)
{
assert(is_jump(inst));
assert(is_jump(target));
@@ -8938,11 +9087,11 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
{
assert(PyDict_CheckExact(const_cache));
assert(PyList_CheckExact(consts));
- struct instr nop;
+ struct cfg_instr nop;
INSTR_SET_OP0(&nop, NOP);
- struct instr *target;
+ struct cfg_instr *target;
for (int i = 0; i < bb->b_iused; i++) {
- struct instr *inst = &bb->b_instr[i];
+ struct cfg_instr *inst = &bb->b_instr[i];
int oparg = inst->i_oparg;
int nextop = i+1 < bb->b_iused ? bb->b_instr[i+1].i_opcode : 0;
if (HAS_TARGET(inst->i_opcode)) {
@@ -9179,7 +9328,7 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
*/
static int
inline_small_exit_blocks(basicblock *bb) {
- struct instr *last = basicblock_last_instr(bb);
+ struct cfg_instr *last = basicblock_last_instr(bb);
if (last == NULL) {
return 0;
}
@@ -9287,7 +9436,7 @@ mark_reachable(basicblock *entryblock) {
}
for (int i = 0; i < b->b_iused; i++) {
basicblock *target;
- struct instr *instr = &b->b_instr[i];
+ struct cfg_instr *instr = &b->b_instr[i];
if (is_jump(instr) || is_block_push(instr)) {
target = instr->i_target;
if (!target->b_visited) {
@@ -9318,7 +9467,7 @@ eliminate_empty_basic_blocks(cfg_builder *g) {
for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
assert(b->b_iused > 0);
for (int i = 0; i < b->b_iused; i++) {
- struct instr *instr = &b->b_instr[i];
+ struct cfg_instr *instr = &b->b_instr[i];
if (HAS_TARGET(instr->i_opcode)) {
basicblock *target = instr->i_target;
while (target->b_iused == 0) {
@@ -9342,7 +9491,7 @@ eliminate_empty_basic_blocks(cfg_builder *g) {
static void
propagate_line_numbers(basicblock *entryblock) {
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
- struct instr *last = basicblock_last_instr(b);
+ struct cfg_instr *last = basicblock_last_instr(b);
if (last == NULL) {
continue;
}
@@ -9398,7 +9547,7 @@ translate_jump_labels_to_targets(basicblock *entryblock)
}
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
for (int i = 0; i < b->b_iused; i++) {
- struct instr *instr = &b->b_instr[i];
+ struct cfg_instr *instr = &b->b_instr[i];
assert(instr->i_target == NULL);
if (HAS_TARGET(instr->i_opcode)) {
int lbl = instr->i_oparg;
@@ -9584,7 +9733,7 @@ duplicate_exits_without_lineno(cfg_builder *g)
*/
basicblock *entryblock = g->g_entryblock;
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
- struct instr *last = basicblock_last_instr(b);
+ struct cfg_instr *last = basicblock_last_instr(b);
assert(last != NULL);
if (is_jump(last)) {
basicblock *target = last->i_target;
@@ -9608,7 +9757,7 @@ duplicate_exits_without_lineno(cfg_builder *g)
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
if (BB_HAS_FALLTHROUGH(b) && b->b_next && b->b_iused > 0) {
if (is_exit_without_lineno(b->b_next)) {
- struct instr *last = basicblock_last_instr(b);
+ struct cfg_instr *last = basicblock_last_instr(b);
assert(last != NULL);
b->b_next->b_instr[0].i_loc = last->i_loc;
}
@@ -9724,7 +9873,7 @@ cfg_to_instructions(cfg_builder *g)
}
for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
for (int i = 0; i < b->b_iused; i++) {
- struct instr *instr = &b->b_instr[i];
+ struct cfg_instr *instr = &b->b_instr[i];
location loc = instr->i_loc;
int arg = HAS_TARGET(instr->i_opcode) ?
instr->i_target->b_label : instr->i_oparg;
@@ -9783,16 +9932,19 @@ _PyCompile_CodeGen(PyObject *ast, PyObject *filename, PyCompilerFlags *pflags,
goto finally;
}
- cfg_builder *g = CFG_BUILDER(c);
-
- if (translate_jump_labels_to_targets(g->g_entryblock) < 0) {
+ cfg_builder g;
+ if (instr_sequence_to_cfg(INSTR_SEQUENCE(c), &g) < 0) {
+ goto finally;
+ }
+ if (translate_jump_labels_to_targets(g.g_entryblock) < 0) {
goto finally;
}
- res = cfg_to_instructions(g);
+ res = cfg_to_instructions(&g);
finally:
compiler_exit_scope(c);
+ cfg_builder_fini(&g);
compiler_free(c);
_PyArena_Free(arena);
return res;
@@ -9815,7 +9967,7 @@ _PyCompile_OptimizeCfg(PyObject *instructions, PyObject *consts)
if (const_cache == NULL) {
goto error;
}
- if (translate_jump_labels_to_targets(g.g_entryblock)) {
+ if (translate_jump_labels_to_targets(g.g_entryblock) < 0) {
goto error;
}
if (optimize_cfg(&g, consts, const_cache) < 0) {
diff --git a/Python/errors.c b/Python/errors.c
index f573bed3d63ef0..bbf6d397ce8097 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -149,9 +149,16 @@ _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value)
exception);
return;
}
- Py_XINCREF(value);
/* Normalize the exception */
- if (value == NULL || (PyObject *)Py_TYPE(value) != exception) {
+ int is_subclass = 0;
+ if (value != NULL && PyExceptionInstance_Check(value)) {
+ is_subclass = PyObject_IsSubclass((PyObject *)Py_TYPE(value), exception);
+ if (is_subclass < 0) {
+ return;
+ }
+ }
+ Py_XINCREF(value);
+ if (!is_subclass) {
/* We must normalize the value right now */
PyObject *fixed_value;
@@ -206,9 +213,10 @@ _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value)
Py_DECREF(exc_value);
}
}
- if (value != NULL && PyExceptionInstance_Check(value))
+ assert(value != NULL);
+ if (PyExceptionInstance_Check(value))
tb = PyException_GetTraceback(value);
- _PyErr_Restore(tstate, Py_XNewRef(exception), value, tb);
+ _PyErr_Restore(tstate, Py_NewRef(Py_TYPE(value)), value, tb);
}
void
diff --git a/README.rst b/README.rst
index b1756e20c141ab..6923b692f6c971 100644
--- a/README.rst
+++ b/README.rst
@@ -1,4 +1,4 @@
-This is Python version 3.12.0 alpha 5
+This is Python version 3.12.0 alpha 6
=====================================
.. image:: /~https://github.com/python/cpython/workflows/Tests/badge.svg