From 1b6acaad9a18b2498386c60f24351ab749061e3a Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Wed, 23 Mar 2022 23:15:25 +0200 Subject: [PATCH 001/237] [3.10] bpo-47101: list only activated algorithms in hashlib.algorithms_available (GH-32076) (GH-32085) Co-authored-by: Christian Heimes --- Lib/test/test_hashlib.py | 4 ++++ .../2022-03-23-15-31-02.bpo-47101.rVSld-.rst | 4 ++++ Modules/_hashopenssl.c | 13 ++++++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index ea31f8be2cb82b..535f4aa3e04cab 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -221,6 +221,10 @@ def test_algorithms_guaranteed(self): def test_algorithms_available(self): self.assertTrue(set(hashlib.algorithms_guaranteed). issubset(hashlib.algorithms_available)) + # all available algorithms must be loadable, bpo-47101 + self.assertNotIn("undefined", hashlib.algorithms_available) + for name in hashlib.algorithms_available: + digest = hashlib.new(name, usedforsecurity=False) def test_usedforsecurity_true(self): hashlib.new("sha256", usedforsecurity=True) diff --git a/Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst b/Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst new file mode 100644 index 00000000000000..1a65024e69fbdc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst @@ -0,0 +1,4 @@ +:const:`hashlib.algorithms_available` now lists only algorithms that are +provided by activated crypto providers on OpenSSL 3.0. Legacy algorithms are +not listed unless the legacy provider has been loaded into the default +OSSL context. diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 65538f63f7bf42..75063fa15369ac 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -1836,15 +1836,21 @@ typedef struct _internal_name_mapper_state { /* A callback function to pass to OpenSSL's OBJ_NAME_do_all(...) */ static void +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +_openssl_hash_name_mapper(EVP_MD *md, void *arg) +#else _openssl_hash_name_mapper(const EVP_MD *md, const char *from, const char *to, void *arg) +#endif { _InternalNameMapperState *state = (_InternalNameMapperState *)arg; PyObject *py_name; assert(state != NULL); - if (md == NULL) + // ignore all undefined providers + if ((md == NULL) || (EVP_MD_nid(md) == NID_undef)) { return; + } py_name = py_digest_name(md); if (py_name == NULL) { @@ -1870,7 +1876,12 @@ hashlib_md_meth_names(PyObject *module) return -1; } +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + // get algorithms from all activated providers in default context + EVP_MD_do_all_provided(NULL, &_openssl_hash_name_mapper, &state); +#else EVP_MD_do_all(&_openssl_hash_name_mapper, &state); +#endif if (state.error) { Py_DECREF(state.set); From 9e1bfd8ce79b947dc0c1cfb4644e5afe337c2d07 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 23 Mar 2022 14:43:32 -0700 Subject: [PATCH 002/237] bpo-47104: Rewrite asyncio.to_thread tests to use IsolatedAsyncioTestCase (GH-32086) (cherry picked from commit ff619c7dfe8dcb0e4c8dc655abc3acc7dc586d0d) Co-authored-by: Andrew Svetlov --- Lib/test/test_asyncio/test_threads.py | 65 +++++-------------- .../2022-03-23-22-45-51.bpo-47104._esUq8.rst | 2 + 2 files changed, 20 insertions(+), 47 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2022-03-23-22-45-51.bpo-47104._esUq8.rst diff --git a/Lib/test/test_asyncio/test_threads.py b/Lib/test/test_asyncio/test_threads.py index 2af322421dacfa..1138a93e0f78ec 100644 --- a/Lib/test/test_asyncio/test_threads.py +++ b/Lib/test/test_asyncio/test_threads.py @@ -5,87 +5,58 @@ from contextvars import ContextVar from unittest import mock -from test.test_asyncio import utils as test_utils def tearDownModule(): asyncio.set_event_loop_policy(None) -class ToThreadTests(test_utils.TestCase): - def setUp(self): - super().setUp() - self.loop = asyncio.new_event_loop() - asyncio.set_event_loop(self.loop) - - def tearDown(self): - self.loop.run_until_complete( - self.loop.shutdown_default_executor()) - self.loop.close() - asyncio.set_event_loop(None) - self.loop = None - super().tearDown() - - def test_to_thread(self): - async def main(): - return await asyncio.to_thread(sum, [40, 2]) - - result = self.loop.run_until_complete(main()) +class ToThreadTests(unittest.IsolatedAsyncioTestCase): + async def test_to_thread(self): + result = await asyncio.to_thread(sum, [40, 2]) self.assertEqual(result, 42) - def test_to_thread_exception(self): + async def test_to_thread_exception(self): def raise_runtime(): raise RuntimeError("test") - async def main(): - await asyncio.to_thread(raise_runtime) - with self.assertRaisesRegex(RuntimeError, "test"): - self.loop.run_until_complete(main()) + await asyncio.to_thread(raise_runtime) - def test_to_thread_once(self): + async def test_to_thread_once(self): func = mock.Mock() - async def main(): - await asyncio.to_thread(func) - - self.loop.run_until_complete(main()) + await asyncio.to_thread(func) func.assert_called_once() - def test_to_thread_concurrent(self): + async def test_to_thread_concurrent(self): func = mock.Mock() - async def main(): - futs = [] - for _ in range(10): - fut = asyncio.to_thread(func) - futs.append(fut) - await asyncio.gather(*futs) + futs = [] + for _ in range(10): + fut = asyncio.to_thread(func) + futs.append(fut) + await asyncio.gather(*futs) - self.loop.run_until_complete(main()) self.assertEqual(func.call_count, 10) - def test_to_thread_args_kwargs(self): + async def test_to_thread_args_kwargs(self): # Unlike run_in_executor(), to_thread() should directly accept kwargs. func = mock.Mock() - async def main(): - await asyncio.to_thread(func, 'test', something=True) + await asyncio.to_thread(func, 'test', something=True) - self.loop.run_until_complete(main()) func.assert_called_once_with('test', something=True) - def test_to_thread_contextvars(self): + async def test_to_thread_contextvars(self): test_ctx = ContextVar('test_ctx') def get_ctx(): return test_ctx.get() - async def main(): - test_ctx.set('parrot') - return await asyncio.to_thread(get_ctx) + test_ctx.set('parrot') + result = await asyncio.to_thread(get_ctx) - result = self.loop.run_until_complete(main()) self.assertEqual(result, 'parrot') diff --git a/Misc/NEWS.d/next/Tests/2022-03-23-22-45-51.bpo-47104._esUq8.rst b/Misc/NEWS.d/next/Tests/2022-03-23-22-45-51.bpo-47104._esUq8.rst new file mode 100644 index 00000000000000..1369bc227f5f24 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-03-23-22-45-51.bpo-47104._esUq8.rst @@ -0,0 +1,2 @@ +Rewrite :func:`asyncio.to_thread` tests to use +:class:`unittest.IsolatedAsyncioTestCase`. From 4d37dc69bd5528ff75b8a9c58f6b66dd3c811bae Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Thu, 24 Mar 2022 10:30:34 +0000 Subject: [PATCH 003/237] Post 3.10.4 --- Include/patchlevel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 482069c791a91f..3c4c0debce4cc2 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -23,7 +23,7 @@ #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.10.4" +#define PY_VERSION "3.10.4+" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. From 48b3ae9e29545891bece874b4c0c0e394fe0f048 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 25 Mar 2022 17:21:50 -0700 Subject: [PATCH 004/237] bpo-47105: Cite grp.h instead of pwd.h in grp docs (GH-32091) (GH-32120) (cherry picked from commit ee912ad6f66bb8cf5a8a2b4a7ecd2752bf070864) Co-authored-by: Alex Hedges --- Doc/library/grp.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/grp.rst b/Doc/library/grp.rst index 74de3f952005fd..fbfb922d3e0528 100644 --- a/Doc/library/grp.rst +++ b/Doc/library/grp.rst @@ -12,7 +12,7 @@ Unix versions. Group database entries are reported as a tuple-like object, whose attributes correspond to the members of the ``group`` structure (Attribute field below, see -````): +````): +-------+-----------+---------------------------------+ | Index | Attribute | Meaning | From 27ee43183437c473725eba00def0ea7647688926 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Sat, 26 Mar 2022 18:26:05 +0000 Subject: [PATCH 005/237] [3.10] bpo-47117: Don't crash if we fail to decode characters when the tokenizer buffers are uninitialized (GH-32129) (GH-32130) Automerge-Triggered-By: GH:pablogsal. (cherry picked from commit 26cca8067bf5306e372c0e90036d832c5021fd90) Co-authored-by: Pablo Galindo Salgado --- .../2022-03-26-15-45-57.bpo-47117.60W6GQ.rst | 2 ++ Parser/pegen.c | 9 +++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-03-26-15-45-57.bpo-47117.60W6GQ.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-26-15-45-57.bpo-47117.60W6GQ.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-26-15-45-57.bpo-47117.60W6GQ.rst new file mode 100644 index 00000000000000..5098ed86d07935 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-26-15-45-57.bpo-47117.60W6GQ.rst @@ -0,0 +1,2 @@ +Fix a crash if we fail to decode characters in interactive mode if the +tokenizer buffers are uninitialized. Patch by Pablo Galindo. diff --git a/Parser/pegen.c b/Parser/pegen.c index df17476013447e..90a6ab98cf42e9 100644 --- a/Parser/pegen.c +++ b/Parser/pegen.c @@ -435,7 +435,12 @@ get_error_line(Parser *p, Py_ssize_t lineno) assert((p->tok->fp == NULL && p->tok->str != NULL) || p->tok->fp == stdin); char *cur_line = p->tok->fp_interactive ? p->tok->interactive_src_start : p->tok->str; - assert(cur_line != NULL); + if (cur_line == NULL) { + assert(p->tok->fp_interactive); + // We can reach this point if the tokenizer buffers for interactive source have not been + // initialized because we failed to decode the original source with the given locale. + return PyUnicode_FromStringAndSize("", 0); + } const char* buf_end = p->tok->fp_interactive ? p->tok->interactive_src_end : p->tok->inp; Py_ssize_t relative_lineno = p->starting_lineno ? lineno - p->starting_lineno + 1 : lineno; @@ -495,7 +500,7 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype, goto error; } - if (p->tok->fp_interactive) { + if (p->tok->fp_interactive && p->tok->interactive_src_start != NULL) { error_line = get_error_line(p, lineno); } else if (p->start_rule == Py_file_input) { From 9194a7b8990a0feec1209b1e5694df3bf42906d8 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 28 Mar 2022 20:06:16 +0300 Subject: [PATCH 006/237] bpo-47138: Fix documentation build by pinning Jinja version to 3.0.3 (GH-32154) Co-authored-by: Maciej Olko --- Doc/requirements.txt | 2 ++ .../next/Documentation/2022-03-28-12-29-42.bpo-47138.2B4N-k.rst | 1 + 2 files changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Documentation/2022-03-28-12-29-42.bpo-47138.2B4N-k.rst diff --git a/Doc/requirements.txt b/Doc/requirements.txt index 95d320f4cb1f33..793df32ecf65f6 100644 --- a/Doc/requirements.txt +++ b/Doc/requirements.txt @@ -8,6 +8,8 @@ sphinx==3.2.1 # version 3.2.1. It can be removed after bumping Sphinx version to at # least 3.5.4. docutils==0.17.1 +# Jinja version is pinned to a version compatible with Sphinx version 3.2.1. +jinja2==3.0.3 blurb diff --git a/Misc/NEWS.d/next/Documentation/2022-03-28-12-29-42.bpo-47138.2B4N-k.rst b/Misc/NEWS.d/next/Documentation/2022-03-28-12-29-42.bpo-47138.2B4N-k.rst new file mode 100644 index 00000000000000..e15148b73b23b4 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-03-28-12-29-42.bpo-47138.2B4N-k.rst @@ -0,0 +1 @@ +Pin Jinja to a version compatible with Sphinx version 3.2.1. From 5944807b09717d43bb017f700e8c451dd07199ed Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 28 Mar 2022 11:26:49 -0700 Subject: [PATCH 007/237] [3.10] bpo-44493: Add missing terminated NUL in sockaddr_un's length (GH-26866) (GH-32140) Add missing terminated NUL in sockaddr_un's length - Linux: https://man7.org/linux/man-pages/man7/unix.7.html - *BSD: SUN_LEN (cherry picked from commit f6b3a07b7df60dc04d0260169ffef6e9796a2124) Co-authored-by: ty Automerge-Triggered-By: GH:gpshead --- .../next/Library/2021-07-26-10-46-49.bpo-44493.xp3CRH.rst | 3 +++ Modules/socketmodule.c | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2021-07-26-10-46-49.bpo-44493.xp3CRH.rst diff --git a/Misc/NEWS.d/next/Library/2021-07-26-10-46-49.bpo-44493.xp3CRH.rst b/Misc/NEWS.d/next/Library/2021-07-26-10-46-49.bpo-44493.xp3CRH.rst new file mode 100644 index 00000000000000..390a7222bbf55f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-07-26-10-46-49.bpo-44493.xp3CRH.rst @@ -0,0 +1,3 @@ +Add missing terminated NUL in sockaddr_un's length + +This was potentially observable when using non-abstract AF_UNIX datagram sockets to processes written in another programming language. diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index ab8618b3415447..392cc32f7fa2f6 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -1680,6 +1680,8 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, "AF_UNIX path too long"); goto unix_out; } + + *len_ret = path.len + offsetof(struct sockaddr_un, sun_path); } else #endif /* linux */ @@ -1691,10 +1693,13 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, goto unix_out; } addr->sun_path[path.len] = 0; + + /* including the tailing NUL */ + *len_ret = path.len + offsetof(struct sockaddr_un, sun_path) + 1; } addr->sun_family = s->sock_family; memcpy(addr->sun_path, path.buf, path.len); - *len_ret = path.len + offsetof(struct sockaddr_un, sun_path); + retval = 1; unix_out: PyBuffer_Release(&path); From 2bcbc3113dee6c35631595ec0d5ee3a8dd2a2ddd Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 28 Mar 2022 15:15:05 -0700 Subject: [PATCH 008/237] bpo-27929: resolve names only for AF_INET/AF_INET6 with asyncio (GH-32131) Co-authored-by: Andrew Svetlov (cherry picked from commit 5c30388f3c586ba2f33e349e22e5949cb92de621) Co-authored-by: Vincent Bernat --- Lib/asyncio/selector_events.py | 3 ++- .../next/Library/2022-03-28-13-35-50.bpo-27929.j5mAmV.rst | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2022-03-28-13-35-50.bpo-27929.j5mAmV.rst diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index 71080b8ad16c61..572d4a8ce12d49 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -487,7 +487,8 @@ async def sock_connect(self, sock, address): if self._debug and sock.gettimeout() != 0: raise ValueError("the socket must be non-blocking") - if not hasattr(socket, 'AF_UNIX') or sock.family != socket.AF_UNIX: + if sock.family == socket.AF_INET or ( + base_events._HAS_IPv6 and sock.family == socket.AF_INET6): resolved = await self._ensure_resolved( address, family=sock.family, type=sock.type, proto=sock.proto, loop=self, diff --git a/Misc/NEWS.d/next/Library/2022-03-28-13-35-50.bpo-27929.j5mAmV.rst b/Misc/NEWS.d/next/Library/2022-03-28-13-35-50.bpo-27929.j5mAmV.rst new file mode 100644 index 00000000000000..4c80a10bc56844 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-28-13-35-50.bpo-27929.j5mAmV.rst @@ -0,0 +1,3 @@ +Fix :meth:`asyncio.loop.sock_connect` to only resolve names for :const:`socket.AF_INET` or +:const:`socket.AF_INET6` families. Resolution may not make sense for other families, +like :const:`socket.AF_BLUETOOTH` and :const:`socket.AF_UNIX`. From 0dfabf9b4a58b835b61fc3d17784d4746f677e56 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Tue, 29 Mar 2022 00:46:18 +0100 Subject: [PATCH 009/237] bpo-47138: Ensure Windows docs build uses the same pinned version as other platforms (GH-32161) --- Doc/make.bat | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/make.bat b/Doc/make.bat index 7fde0636427713..ac66b56e9a3ef7 100644 --- a/Doc/make.bat +++ b/Doc/make.bat @@ -13,7 +13,7 @@ if not defined SPHINXBUILD ( %PYTHON% -c "import sphinx" > nul 2> nul if errorlevel 1 ( echo Installing sphinx with %PYTHON% - %PYTHON% -m pip install sphinx==2.2.0 + %PYTHON% -m pip install -r requirements.txt if errorlevel 1 exit /B ) set SPHINXBUILD=%PYTHON% -c "import sphinx.cmd.build, sys; sys.exit(sphinx.cmd.build.main())" @@ -30,6 +30,7 @@ if not defined BLURB ( %PYTHON% -c "import blurb" > nul 2> nul if errorlevel 1 ( echo Installing blurb with %PYTHON% + rem Should have been installed with Sphinx earlier %PYTHON% -m pip install blurb if errorlevel 1 exit /B ) From 604d003ab4d1084ef828ebca1b28f2bf1b93c744 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Mon, 28 Mar 2022 19:39:55 -0700 Subject: [PATCH 010/237] [3.10] bpo-28516: document contextlib.ExitStack.__enter__ behavior (GH-31636) (GH-32171) The enter_context is updated with following information: 'The :meth:`__enter__` method returns the ExitStack instance, and performs no additional operations.' Co-authored-by: Jelle Zijlstra (cherry picked from commit 86384cf83f96fcaec03e2ad6516e2e24f20d3b92) Co-authored-by: vidhya <96202776+Vidhyavinu@users.noreply.github.com> --- Doc/library/contextlib.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst index b6ec6b8c876bee..0fe3206540e80d 100644 --- a/Doc/library/contextlib.rst +++ b/Doc/library/contextlib.rst @@ -485,6 +485,9 @@ Functions and classes provided: # the with statement, even if attempts to open files later # in the list raise an exception + The :meth:`__enter__` method returns the :class:`ExitStack` instance, and + performs no additional operations. + Each instance maintains a stack of registered callbacks that are called in reverse order when the instance is closed (either explicitly or implicitly at the end of a :keyword:`with` statement). Note that callbacks are *not* From 11408ff47e7b05b7979f7c5fa29567312960a16e Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 28 Mar 2022 19:47:57 -0700 Subject: [PATCH 011/237] ctypes docs: Fix array-length reference to "non-negative" from "positive" (GH-32097) (GH-32142) (cherry picked from commit 76f14b0463dc2c53911eaf95e85374e511ba9bcc) Co-authored-by: Yonatan Goldschmidt Co-authored-by: Jelle Zijlstra --- Doc/library/ctypes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index c10e54f153243f..7665f214916db0 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -2513,7 +2513,7 @@ Arrays and pointers Abstract base class for arrays. The recommended way to create concrete array types is by multiplying any - :mod:`ctypes` data type with a positive integer. Alternatively, you can subclass + :mod:`ctypes` data type with a non-negative integer. Alternatively, you can subclass this type and define :attr:`_length_` and :attr:`_type_` class variables. Array elements can be read and written using standard subscript and slice accesses; for slice reads, the resulting object is From 370900d7d8ba29eb52e419c3163599b4ac55f121 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 28 Mar 2022 21:21:27 -0700 Subject: [PATCH 012/237] Fix typo in the sqlite3 docs (GH-31915) (GH-32157) Co-authored-by: Jonathan <89750679+AHypnotoad@users.noreply.github.com> (cherry picked from commit 66584c890d016e40d707400130d1cd98f2aedde9) Co-authored-by: Jonathan Co-authored-by: Jelle Zijlstra --- Lib/sqlite3/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/sqlite3/__init__.py b/Lib/sqlite3/__init__.py index 0dedf186b1a1eb..5a2dbd360fb49f 100644 --- a/Lib/sqlite3/__init__.py +++ b/Lib/sqlite3/__init__.py @@ -21,7 +21,7 @@ # 3. This notice may not be removed or altered from any source distribution. """ -The sqlite3 extension module provides a DB-API 2.0 (PEP 249) compilant +The sqlite3 extension module provides a DB-API 2.0 (PEP 249) compliant interface to the SQLite library, and requires SQLite 3.7.15 or newer. To use the module, start by creating a database Connection object: From 66cde7c51a871a86cf8667adf4bd1d03e9b98eb1 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 29 Mar 2022 14:45:47 -0700 Subject: [PATCH 013/237] bpo-42340: Document issues around KeyboardInterrupt (GH-23255) Update documentation to note that in some circumstances, KeyboardInterrupt may cause code to enter an inconsistent state. Also document sample workaround to avoid KeyboardInterrupt, if needed. (cherry picked from commit d0906c90fcfbc4cfb9bb963eaa6bb152dd543b56) Co-authored-by: benfogle --- Doc/library/exceptions.rst | 9 +++ Doc/library/signal.rst | 70 +++++++++++++++++++ .../2020-11-12-21-26-31.bpo-42340.apumUL.rst | 3 + 3 files changed, 82 insertions(+) create mode 100644 Misc/NEWS.d/next/Documentation/2020-11-12-21-26-31.bpo-42340.apumUL.rst diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst index 2f97bb8131d78a..50a3ff3452c99e 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -246,6 +246,15 @@ The following exceptions are the exceptions that are usually raised. accidentally caught by code that catches :exc:`Exception` and thus prevent the interpreter from exiting. + .. note:: + + Catching a :exc:`KeyboardInterrupt` requires special consideration. + Because it can be raised at unpredictable points, it may, in some + circumstances, leave the running program in an inconsistent state. It is + generally best to allow :exc:`KeyboardInterrupt` to end the program as + quickly as possible or avoid raising it entirely. (See + :ref:`handlers-and-exceptions`.) + .. exception:: MemoryError diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index 84a569d03eb293..11bdfc8e82831d 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -46,6 +46,9 @@ This has consequences: arbitrary amount of time, regardless of any signals received. The Python signal handlers will be called when the calculation finishes. +* If the handler raises an exception, it will be raised "out of thin air" in + the main thread. See the :ref:`note below ` for a + discussion. .. _signals-and-threads: @@ -677,3 +680,70 @@ Do not set :const:`SIGPIPE`'s disposition to :const:`SIG_DFL` in order to avoid :exc:`BrokenPipeError`. Doing that would cause your program to exit unexpectedly also whenever any socket connection is interrupted while your program is still writing to it. + +.. _handlers-and-exceptions: + +Note on Signal Handlers and Exceptions +-------------------------------------- + +If a signal handler raises an exception, the exception will be propagated to +the main thread and may be raised after any :term:`bytecode` instruction. Most +notably, a :exc:`KeyboardInterrupt` may appear at any point during execution. +Most Python code, including the standard library, cannot be made robust against +this, and so a :exc:`KeyboardInterrupt` (or any other exception resulting from +a signal handler) may on rare occasions put the program in an unexpected state. + +To illustrate this issue, consider the following code:: + + class SpamContext: + def __init__(self): + self.lock = threading.Lock() + + def __enter__(self): + # If KeyboardInterrupt occurs here, everything is fine + self.lock.acquire() + # If KeyboardInterrupt occcurs here, __exit__ will not be called + ... + # KeyboardInterrupt could occur just before the function returns + + def __exit__(self, exc_type, exc_val, exc_tb): + ... + self.lock.release() + +For many programs, especially those that merely want to exit on +:exc:`KeyboardInterrupt`, this is not a problem, but applications that are +complex or require high reliability should avoid raising exceptions from signal +handlers. They should also avoid catching :exc:`KeyboardInterrupt` as a means +of gracefully shutting down. Instead, they should install their own +:const:`SIGINT` handler. Below is an example of an HTTP server that avoids +:exc:`KeyboardInterrupt`:: + + import signal + import socket + from selectors import DefaultSelector, EVENT_READ + from http.server import HTTPServer, SimpleHTTPRequestHandler + + interrupt_read, interrupt_write = socket.socketpair() + + def handler(signum, frame): + print('Signal handler called with signal', signum) + interrupt_write.send(b'\0') + signal.signal(signal.SIGINT, handler) + + def serve_forever(httpd): + sel = DefaultSelector() + sel.register(interrupt_read, EVENT_READ) + sel.register(httpd, EVENT_READ) + + while True: + for key, _ in sel.select(): + if key.fileobj == interrupt_read: + interrupt_read.recv(1) + return + if key.fileobj == httpd: + httpd.handle_request() + + print("Serving on port 8000") + httpd = HTTPServer(('', 8000), SimpleHTTPRequestHandler) + serve_forever(httpd) + print("Shutdown...") diff --git a/Misc/NEWS.d/next/Documentation/2020-11-12-21-26-31.bpo-42340.apumUL.rst b/Misc/NEWS.d/next/Documentation/2020-11-12-21-26-31.bpo-42340.apumUL.rst new file mode 100644 index 00000000000000..aa6857497383c6 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-11-12-21-26-31.bpo-42340.apumUL.rst @@ -0,0 +1,3 @@ +Document that in some circumstances :exc:`KeyboardInterrupt` may cause the +code to enter an inconsistent state. Provided a sample workaround to avoid +it if needed. From 1f2ec4cef1804cda9d2df99a318373b2982919e9 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 30 Mar 2022 18:48:31 -0700 Subject: [PATCH 014/237] bpo-46775: OSError should call winerror_to_errno unconditionally on Windows (GH-32179) (cherry picked from commit d0c67ea0645b7ad37b867c167882a346a24de641) Co-authored-by: Dong-hee Na --- .../2022-03-30-02-36-25.bpo-46775.e3Oxqf.rst | 3 +++ Objects/exceptions.c | 9 +-------- 2 files changed, 4 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-03-30-02-36-25.bpo-46775.e3Oxqf.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-30-02-36-25.bpo-46775.e3Oxqf.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-30-02-36-25.bpo-46775.e3Oxqf.rst new file mode 100644 index 00000000000000..da56ecd89367b8 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-30-02-36-25.bpo-46775.e3Oxqf.rst @@ -0,0 +1,3 @@ +Some Windows system error codes(>= 10000) are now mapped into +the correct errno and may now raise a subclass of :exc:`OSError`. +Patch by Dong-hee Na. diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 6537a7ccd1e3c6..9639b4436a078b 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -847,14 +847,7 @@ oserror_parse_args(PyObject **p_args, winerrcode = PyLong_AsLong(*winerror); if (winerrcode == -1 && PyErr_Occurred()) return -1; - /* Set errno to the corresponding POSIX errno (overriding - first argument). Windows Socket error codes (>= 10000) - have the same value as their POSIX counterparts. - */ - if (winerrcode < 10000) - errcode = winerror_to_errno(winerrcode); - else - errcode = winerrcode; + errcode = winerror_to_errno(winerrcode); *myerrno = PyLong_FromLong(errcode); if (!*myerrno) return -1; From 625f6704c0d783360574bbab2f78b0b9bbed5891 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 31 Mar 2022 07:23:04 -0700 Subject: [PATCH 015/237] bpo-14911: Corrected generator.throw() documentation (GH-32207) Co-authored-by: Andrew Svetlov (cherry picked from commit 8be7c2bc5ad5e295f0f855bb31db412eef2c7c92) Co-authored-by: Dave Goncalves --- Doc/howto/functional.rst | 2 +- Doc/reference/datamodel.rst | 3 ++- Doc/reference/expressions.rst | 17 +++++++++++++++-- Objects/genobject.c | 14 ++++++++++---- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/Doc/howto/functional.rst b/Doc/howto/functional.rst index c7f8bc8f17f43b..695b9b31a762bd 100644 --- a/Doc/howto/functional.rst +++ b/Doc/howto/functional.rst @@ -589,7 +589,7 @@ generator function. In addition to :meth:`~generator.send`, there are two other methods on generators: -* :meth:`throw(type, value=None, traceback=None) ` is used to +* :meth:`throw(value) ` is used to raise an exception inside the generator; the exception is raised by the ``yield`` expression where the generator's execution is paused. diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 3c32210a6ac7b0..a5739e6e5e4723 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -2913,7 +2913,8 @@ generators, coroutines do not directly support iteration. :exc:`StopIteration`, or other exception) is the same as when iterating over the :meth:`__await__` return value, described above. -.. method:: coroutine.throw(type[, value[, traceback]]) +.. method:: coroutine.throw(value) + coroutine.throw(type[, value[, traceback]]) Raises the specified exception in the coroutine. This method delegates to the :meth:`~generator.throw` method of the iterator that caused diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 9f136c9a88ff3c..f77927d86d9d66 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -556,14 +556,27 @@ is already executing raises a :exc:`ValueError` exception. could receive the value. -.. method:: generator.throw(type[, value[, traceback]]) +.. method:: generator.throw(value) + generator.throw(type[, value[, traceback]]) - Raises an exception of type ``type`` at the point where the generator was paused, + Raises an exception at the point where the generator was paused, and returns the next value yielded by the generator function. If the generator exits without yielding another value, a :exc:`StopIteration` exception is raised. If the generator function does not catch the passed-in exception, or raises a different exception, then that exception propagates to the caller. + In typical use, this is called with a single exception instance similar to the + way the :keyword:`raise` keyword is used. + + For backwards compatability, however, the second signature is + supported, following a convention from older versions of Python. + The *type* argument should be an exception class, and *value* + should be an exception instance. If the *value* is not provided, the + *type* constructor is called to get an instance. If *traceback* + is provided, it is set on the exception, otherwise any existing + :attr:`~BaseException.__traceback__` attribute stored in *value* may + be cleared. + .. index:: exception: GeneratorExit diff --git a/Objects/genobject.c b/Objects/genobject.c index 33fc4a592492a8..123c17aae7e7c0 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -403,8 +403,11 @@ gen_close(PyGenObject *gen, PyObject *args) PyDoc_STRVAR(throw_doc, -"throw(typ[,val[,tb]]) -> raise exception in generator,\n\ -return next yielded value or raise StopIteration."); +"throw(value)\n\ +throw(type[,value[,tb]])\n\ +\n\ +Raise exception in generator, return next yielded value or raise\n\ +StopIteration."); static PyObject * _gen_throw(PyGenObject *gen, int close_on_genexit, @@ -1001,8 +1004,11 @@ PyDoc_STRVAR(coro_send_doc, return next iterated value or raise StopIteration."); PyDoc_STRVAR(coro_throw_doc, -"throw(typ[,val[,tb]]) -> raise exception in coroutine,\n\ -return next iterated value or raise StopIteration."); +"throw(value)\n\ +throw(type[,value[,traceback]])\n\ +\n\ +Raise exception in coroutine, return next iterated value or raise\n\ +StopIteration."); PyDoc_STRVAR(coro_close_doc, "close() -> raise GeneratorExit inside coroutine."); From 9ed179b07df6ce7432f972f5d069a7c8dee56e79 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 31 Mar 2022 14:09:50 -0700 Subject: [PATCH 016/237] bpo-47151: Fallback to fork when vfork fails in subprocess. (GH-32186) bpo-47151: Fallback to fork when vfork fails in subprocess. An OS kernel can specifically decide to disallow vfork() in a process. No need for that to prevent us from launching subprocesses. (cherry picked from commit 4a08c4c469d36f99d3a5e0f17ad82ab35dcf2835) Co-authored-by: Gregory P. Smith --- .../next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst | 3 +++ Modules/_posixsubprocess.c | 6 ++++++ 2 files changed, 9 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst diff --git a/Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst b/Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst new file mode 100644 index 00000000000000..d4d02459d35de1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst @@ -0,0 +1,3 @@ +When subprocess tries to use vfork, it now falls back to fork if vfork +returns an error. This allows use in situations where vfork isn't allowed +by the OS kernel. diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index a58159a277bea8..18a81c6ed8b353 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -681,6 +681,12 @@ do_fork_exec(char *const exec_array[], assert(preexec_fn == Py_None); pid = vfork(); + if (pid == -1) { + /* If vfork() fails, fall back to using fork(). When it isn't + * allowed in a process by the kernel, vfork can return -1 + * with errno EINVAL. https://bugs.python.org/issue47151. */ + pid = fork(); + } } else #endif { From 55d5c96c57738766eb6f3b5ccfa6599d5f094c18 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Fri, 1 Apr 2022 11:44:56 +0300 Subject: [PATCH 017/237] [3.10] bpo-47182: Fix crash by named unicode characters after interpreter reinitialization (GH-32212) (GH-32216) Co-authored-by: Christian Heimes --- .../Core and Builtins/2022-03-31-15-37-02.bpo-47182.e_4SsC.rst | 2 ++ Objects/unicodeobject.c | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-03-31-15-37-02.bpo-47182.e_4SsC.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-31-15-37-02.bpo-47182.e_4SsC.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-31-15-37-02.bpo-47182.e_4SsC.rst new file mode 100644 index 00000000000000..08036bc680933b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-31-15-37-02.bpo-47182.e_4SsC.rst @@ -0,0 +1,2 @@ +Fix a crash when using a named unicode character like ``"\N{digit nine}"`` +after the main interpreter has been initialized a second time. diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 077cf8d7f45605..377fa6c8e2a28b 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -16352,6 +16352,9 @@ _PyUnicode_Fini(PyInterpreterState *interp) if (_Py_IsMainInterpreter(interp)) { // _PyUnicode_ClearInterned() must be called before _PyUnicode_Fini() assert(interned == NULL); + // bpo-47182: force a unicodedata CAPI capsule re-import on + // subsequent initialization of main interpreter. + ucnhash_capi = NULL; } _PyUnicode_FiniEncodings(&state->fs_codec); From 1069d529590850e87a11b8c559a7fb296e9c626a Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 1 Apr 2022 13:38:35 -0700 Subject: [PATCH 018/237] bpo-47089: Avoid test_compileall failures on Windows (GH-32037) (cherry picked from commit 76b8a075b8a79b08468fd0ed06a489a5c815bc11) Co-authored-by: Jeremy Kloth --- Lib/test/test_compileall.py | 84 ++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 48 deletions(-) diff --git a/Lib/test/test_compileall.py b/Lib/test/test_compileall.py index 33f0c939325f53..a7318bf404c3bc 100644 --- a/Lib/test/test_compileall.py +++ b/Lib/test/test_compileall.py @@ -457,31 +457,29 @@ def test_error(self): class CommandLineTestsBase: """Test compileall's CLI.""" - @classmethod - def setUpClass(cls): - for path in filter(os.path.isdir, sys.path): - directory_created = False - directory = pathlib.Path(path) / '__pycache__' - path = directory / 'test.try' - try: - if not directory.is_dir(): - directory.mkdir() - directory_created = True - path.write_text('# for test_compileall', encoding="utf-8") - except OSError: - sys_path_writable = False - break - finally: - os_helper.unlink(str(path)) - if directory_created: - directory.rmdir() - else: - sys_path_writable = True - cls._sys_path_writable = sys_path_writable - - def _skip_if_sys_path_not_writable(self): - if not self._sys_path_writable: - raise unittest.SkipTest('not all entries on sys.path are writable') + def setUp(self): + self.directory = tempfile.mkdtemp() + self.addCleanup(os_helper.rmtree, self.directory) + self.pkgdir = os.path.join(self.directory, 'foo') + os.mkdir(self.pkgdir) + self.pkgdir_cachedir = os.path.join(self.pkgdir, '__pycache__') + # Create the __init__.py and a package module. + self.initfn = script_helper.make_script(self.pkgdir, '__init__', '') + self.barfn = script_helper.make_script(self.pkgdir, 'bar', '') + + @contextlib.contextmanager + def temporary_pycache_prefix(self): + """Adjust and restore sys.pycache_prefix.""" + old_prefix = sys.pycache_prefix + new_prefix = os.path.join(self.directory, '__testcache__') + try: + sys.pycache_prefix = new_prefix + yield { + 'PYTHONPATH': self.directory, + 'PYTHONPYCACHEPREFIX': new_prefix, + } + finally: + sys.pycache_prefix = old_prefix def _get_run_args(self, args): return [*support.optim_args_from_interpreter_flags(), @@ -509,49 +507,39 @@ def assertNotCompiled(self, fn): path = importlib.util.cache_from_source(fn) self.assertFalse(os.path.exists(path)) - def setUp(self): - self.directory = tempfile.mkdtemp() - self.addCleanup(os_helper.rmtree, self.directory) - self.pkgdir = os.path.join(self.directory, 'foo') - os.mkdir(self.pkgdir) - self.pkgdir_cachedir = os.path.join(self.pkgdir, '__pycache__') - # Create the __init__.py and a package module. - self.initfn = script_helper.make_script(self.pkgdir, '__init__', '') - self.barfn = script_helper.make_script(self.pkgdir, 'bar', '') - def test_no_args_compiles_path(self): # Note that -l is implied for the no args case. - self._skip_if_sys_path_not_writable() bazfn = script_helper.make_script(self.directory, 'baz', '') - self.assertRunOK(PYTHONPATH=self.directory) - self.assertCompiled(bazfn) - self.assertNotCompiled(self.initfn) - self.assertNotCompiled(self.barfn) + with self.temporary_pycache_prefix() as env: + self.assertRunOK(**env) + self.assertCompiled(bazfn) + self.assertNotCompiled(self.initfn) + self.assertNotCompiled(self.barfn) @without_source_date_epoch # timestamp invalidation test def test_no_args_respects_force_flag(self): - self._skip_if_sys_path_not_writable() bazfn = script_helper.make_script(self.directory, 'baz', '') - self.assertRunOK(PYTHONPATH=self.directory) - pycpath = importlib.util.cache_from_source(bazfn) + with self.temporary_pycache_prefix() as env: + self.assertRunOK(**env) + pycpath = importlib.util.cache_from_source(bazfn) # Set atime/mtime backward to avoid file timestamp resolution issues os.utime(pycpath, (time.time()-60,)*2) mtime = os.stat(pycpath).st_mtime # Without force, no recompilation - self.assertRunOK(PYTHONPATH=self.directory) + self.assertRunOK(**env) mtime2 = os.stat(pycpath).st_mtime self.assertEqual(mtime, mtime2) # Now force it. - self.assertRunOK('-f', PYTHONPATH=self.directory) + self.assertRunOK('-f', **env) mtime2 = os.stat(pycpath).st_mtime self.assertNotEqual(mtime, mtime2) def test_no_args_respects_quiet_flag(self): - self._skip_if_sys_path_not_writable() script_helper.make_script(self.directory, 'baz', '') - noisy = self.assertRunOK(PYTHONPATH=self.directory) + with self.temporary_pycache_prefix() as env: + noisy = self.assertRunOK(**env) self.assertIn(b'Listing ', noisy) - quiet = self.assertRunOK('-q', PYTHONPATH=self.directory) + quiet = self.assertRunOK('-q', **env) self.assertNotIn(b'Listing ', quiet) # Ensure that the default behavior of compileall's CLI is to create From 16a809ffb7af14898ce9ec8165960d96cbcd4ec3 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 2 Apr 2022 06:39:03 -0700 Subject: [PATCH 019/237] bpo-47194: Update zlib to v1.2.12 on Windows to resolve CVE-2018-25032 (GH-32241) (cherry picked from commit 6066739ff7794e54c98c08b953a699cbc961cd28) Co-authored-by: Zachary Ware --- .../next/Windows/2022-04-01-14-57-40.bpo-47194.IB0XL4.rst | 1 + PCbuild/get_externals.bat | 2 +- PCbuild/python.props | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2022-04-01-14-57-40.bpo-47194.IB0XL4.rst diff --git a/Misc/NEWS.d/next/Windows/2022-04-01-14-57-40.bpo-47194.IB0XL4.rst b/Misc/NEWS.d/next/Windows/2022-04-01-14-57-40.bpo-47194.IB0XL4.rst new file mode 100644 index 00000000000000..7e76add45fa953 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-04-01-14-57-40.bpo-47194.IB0XL4.rst @@ -0,0 +1 @@ +Update ``zlib`` to v1.2.12 to resolve CVE-2018-25032. diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index 7129898c6bc62f..dc5c909de74418 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -59,7 +59,7 @@ if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.12. if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.12.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tix-8.4.3.6 set libraries=%libraries% xz-5.2.2 -set libraries=%libraries% zlib-1.2.11 +set libraries=%libraries% zlib-1.2.12 for %%e in (%libraries%) do ( if exist "%EXTERNALS_DIR%\%%e" ( diff --git a/PCbuild/python.props b/PCbuild/python.props index 7a11cfafedf5e7..7b42037b7cdf87 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -67,7 +67,7 @@ $(ExternalsDir)openssl-bin-1.1.1n\$(ArchName)\ $(opensslOutDir)include $(ExternalsDir)\nasm-2.11.06\ - $(ExternalsDir)\zlib-1.2.11\ + $(ExternalsDir)\zlib-1.2.12\ _d From 5830a288abc00fc4fca57ebe18e42dc78334a279 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 2 Apr 2022 12:54:04 -0700 Subject: [PATCH 020/237] More minor fixes to C API docs (GH-31714) * init_config: wording fixes * bytearray: remove XXX, there is a good link to the buffer docs * bytes, call, exceptions: minor wording fixes (cherry picked from commit 677a87946630c5fbd9998969669b4dd4f4b32545) Co-authored-by: Jelle Zijlstra --- Doc/c-api/bytearray.rst | 2 -- Doc/c-api/bytes.rst | 2 +- Doc/c-api/call.rst | 2 +- Doc/c-api/exceptions.rst | 6 +++--- Doc/c-api/init_config.rst | 8 ++++---- 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/Doc/c-api/bytearray.rst b/Doc/c-api/bytearray.rst index 30bcfc7cf9f500..85a7d1373c2a81 100644 --- a/Doc/c-api/bytearray.rst +++ b/Doc/c-api/bytearray.rst @@ -42,8 +42,6 @@ Direct API functions Return a new bytearray object from any object, *o*, that implements the :ref:`buffer protocol `. - .. XXX expand about the buffer protocol, at least somewhere - .. c:function:: PyObject* PyByteArray_FromStringAndSize(const char *string, Py_ssize_t len) diff --git a/Doc/c-api/bytes.rst b/Doc/c-api/bytes.rst index de65701037a7c1..32c7b80dc7ac63 100644 --- a/Doc/c-api/bytes.rst +++ b/Doc/c-api/bytes.rst @@ -5,7 +5,7 @@ Bytes Objects ------------- -These functions raise :exc:`TypeError` when expecting a bytes parameter and are +These functions raise :exc:`TypeError` when expecting a bytes parameter and called with a non-bytes parameter. .. index:: object: bytes diff --git a/Doc/c-api/call.rst b/Doc/c-api/call.rst index 739b5e97d15150..cdf72bc1f4714a 100644 --- a/Doc/c-api/call.rst +++ b/Doc/c-api/call.rst @@ -26,7 +26,7 @@ This convention is not only used by *tp_call*: :c:member:`~PyTypeObject.tp_new` and :c:member:`~PyTypeObject.tp_init` also pass arguments this way. -To call an object, use :c:func:`PyObject_Call` or other +To call an object, use :c:func:`PyObject_Call` or another :ref:`call API `. diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index bcd9621681c2e2..7deef83b2789a9 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -281,7 +281,7 @@ For convenience, some of these functions will always return a .. c:function:: void PyErr_SyntaxLocation(const char *filename, int lineno) - Like :c:func:`PyErr_SyntaxLocationEx`, but the col_offset parameter is + Like :c:func:`PyErr_SyntaxLocationEx`, but the *col_offset* parameter is omitted. @@ -333,7 +333,7 @@ an error value). Issue a warning message with explicit control over all warning attributes. This is a straightforward wrapper around the Python function - :func:`warnings.warn_explicit`, see there for more information. The *module* + :func:`warnings.warn_explicit`; see there for more information. The *module* and *registry* arguments may be set to ``NULL`` to get the default effect described there. @@ -441,7 +441,7 @@ Querying the error indicator error indicator. -.. c:function:: void PyErr_NormalizeException(PyObject**exc, PyObject**val, PyObject**tb) +.. c:function:: void PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb) Under certain circumstances, the values returned by :c:func:`PyErr_Fetch` below can be "unnormalized", meaning that ``*exc`` is a class object but ``*val`` is diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst index b8b41510b89ec8..657d8e9caf1eab 100644 --- a/Doc/c-api/init_config.rst +++ b/Doc/c-api/init_config.rst @@ -16,12 +16,12 @@ There are two kinds of configuration: * The :ref:`Python Configuration ` can be used to build a customized Python which behaves as the regular Python. For example, - environments variables and command line arguments are used to configure + environment variables and command line arguments are used to configure Python. * The :ref:`Isolated Configuration ` can be used to embed Python into an application. It isolates Python from the system. For example, - environments variables are ignored, the LC_CTYPE locale is left unchanged and + environment variables are ignored, the LC_CTYPE locale is left unchanged and no signal handler is registered. The :c:func:`Py_RunMain` function can be used to write a customized Python @@ -1287,7 +1287,7 @@ Isolated Configuration isolate Python from the system. For example, to embed Python into an application. -This configuration ignores global configuration variables, environments +This configuration ignores global configuration variables, environment variables, command line arguments (:c:member:`PyConfig.argv` is not parsed) and user site directory. The C standard streams (ex: ``stdout``) and the LC_CTYPE locale are left unchanged. Signal handlers are not installed. @@ -1432,7 +1432,7 @@ Multi-Phase Initialization Private Provisional API ================================================== This section is a private provisional API introducing multi-phase -initialization, the core feature of the :pep:`432`: +initialization, the core feature of :pep:`432`: * "Core" initialization phase, "bare minimum Python": From 319a70cf99c9866c7fa47deecf04f6ebcfe35a54 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 2 Apr 2022 13:19:20 -0700 Subject: [PATCH 021/237] bpo-47031: Improve documentation for `math.nan` (GH-32170) Co-authored-by: Jelle Zijlstra (cherry picked from commit 182e93c3f57b0c72e765c9896066d32e461c0865) Co-authored-by: Charlie Zhao --- Doc/library/math.rst | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/Doc/library/math.rst b/Doc/library/math.rst index 145bac4966e18c..d485ae5c2706a5 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -627,8 +627,23 @@ Constants .. data:: nan - A floating-point "not a number" (NaN) value. Equivalent to the output of - ``float('nan')``. + A floating-point "not a number" (NaN) value. Equivalent to the output of + ``float('nan')``. Due to the requirements of the `IEEE-754 standard + `_, ``math.nan`` and ``float('nan')`` are + not considered to equal to any other numeric value, including themselves. To check + whether a number is a NaN, use the :func:`isnan` function to test + for NaNs instead of ``is`` or ``==``. + Example:: + + >>> import math + >>> math.nan == math.nan + False + >>> float('nan') == float('nan') + False + >>> math.isnan(math.nan) + True + >>> math.isnan(float('nan')) + True .. versionadded:: 3.5 From 23c0200c436714a3f9b38d5e6cac230ceacd4c43 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 2 Apr 2022 14:19:48 -0700 Subject: [PATCH 022/237] bpo-45114: Use lstat() instead of stat() in stat docs example (GH-29845) (cherry picked from commit c93a0ac6972221787d8bea1c41a9feb667ed3d2c) Co-authored-by: 180909 --- Doc/library/stat.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/stat.rst b/Doc/library/stat.rst index 98219eaee97619..083dc5e3bcfd68 100644 --- a/Doc/library/stat.rst +++ b/Doc/library/stat.rst @@ -109,7 +109,7 @@ Example:: for f in os.listdir(top): pathname = os.path.join(top, f) - mode = os.stat(pathname).st_mode + mode = os.lstat(pathname).st_mode if S_ISDIR(mode): # It's a directory, recurse into it walktree(pathname, callback) From 2d936a42ac2b45ddc160eb90178cc9b4107639db Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 2 Apr 2022 14:33:52 -0700 Subject: [PATCH 023/237] codecs docs: fix grammar mistake (GH-29462) (cherry picked from commit ea56845744e815ed468dfbdd835110254c3be997) Co-authored-by: 180909 --- Doc/library/codecs.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst index 1a1ce9237b0102..9e2eb634792823 100644 --- a/Doc/library/codecs.rst +++ b/Doc/library/codecs.rst @@ -912,7 +912,7 @@ there's the so called BOM ("Byte Order Mark"). This is the Unicode character ``U+FEFF``. This character can be prepended to every ``UTF-16`` or ``UTF-32`` byte sequence. The byte swapped version of this character (``0xFFFE``) is an illegal character that may not appear in a Unicode text. So when the -first character in an ``UTF-16`` or ``UTF-32`` byte sequence +first character in a ``UTF-16`` or ``UTF-32`` byte sequence appears to be a ``U+FFFE`` the bytes have to be swapped on decoding. Unfortunately the character ``U+FEFF`` had a second purpose as a ``ZERO WIDTH NO-BREAK SPACE``: a character that has no width and doesn't allow From 8d9a75b206d40b096d9a8f9bcc40d95b7687d6eb Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 2 Apr 2022 15:00:12 -0700 Subject: [PATCH 024/237] os docs: fix typo (GH-28996) Co-authored-by: Jacob Walls (cherry picked from commit 1f80dcd2442f2a354097797fedc077592984903b) Co-authored-by: Vitor Buxbaum Orlandi --- Doc/library/os.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 2a1ea05c5c8333..203995c80fd327 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -113,7 +113,7 @@ of the UTF-8 encoding: :ref:`error handler ` being enabled for :data:`sys.stdin` and :data:`sys.stdout` (:data:`sys.stderr` continues to use ``backslashreplace`` as it does in the default locale-aware mode) -* On Unix, :func:`os.device_encoding` returns ``'UTF-8'``. rather than the +* On Unix, :func:`os.device_encoding` returns ``'UTF-8'`` rather than the device encoding. Note that the standard stream settings in UTF-8 mode can be overridden by From 3031b867531009d270d5d7d3e53e739c4cba8816 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 2 Apr 2022 15:30:59 -0700 Subject: [PATCH 025/237] bpo-45584: Clarify `math.trunc` documentation (GH-29183) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While floor/ceil 's documentation are very precise, `truncate` was not explained. I actually had to search online to understand the difference between `truncate` and `floor` (admittedly, once I remembered that numbers are signed, and that floating numbers actually uses a bit for negation symbol instead of two complement, it became obvious) Co-authored-by: Alex Waygood Co-authored-by: Éric Araujo Co-authored-by: Terry Jan Reedy Co-authored-by: Jelle Zijlstra (cherry picked from commit ebbdbbff5d6840807e46ec61b8a323e94ee88de2) Co-authored-by: Arthur Milchior --- Doc/library/math.rst | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Doc/library/math.rst b/Doc/library/math.rst index d485ae5c2706a5..7ba5fa4a0b4e7f 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -32,8 +32,8 @@ Number-theoretic and representation functions .. function:: ceil(x) Return the ceiling of *x*, the smallest integer greater than or equal to *x*. - If *x* is not a float, delegates to ``x.__ceil__()``, which should return an - :class:`~numbers.Integral` value. + If *x* is not a float, delegates to :meth:`x.__ceil__ `, + which should return an :class:`~numbers.Integral` value. .. function:: comb(n, k) @@ -77,9 +77,9 @@ Number-theoretic and representation functions .. function:: floor(x) - Return the floor of *x*, the largest integer less than or equal to *x*. - If *x* is not a float, delegates to ``x.__floor__()``, which should return an - :class:`~numbers.Integral` value. + Return the floor of *x*, the largest integer less than or equal to *x*. If + *x* is not a float, delegates to :meth:`x.__floor__ `, which + should return an :class:`~numbers.Integral` value. .. function:: fmod(x, y) @@ -298,9 +298,11 @@ Number-theoretic and representation functions .. function:: trunc(x) - Return the :class:`~numbers.Real` value *x* truncated to an - :class:`~numbers.Integral` (usually an integer). Delegates to - :meth:`x.__trunc__() `. + Return *x* with the fractional part + removed, leaving the integer part. This rounds toward 0: ``trunc()`` is + equivalent to :func:`floor` for positive *x*, and equivalent to :func:`ceil` + for negative *x*. If *x* is not a float, delegates to :meth:`x.__trunc__ + `, which should return an :class:`~numbers.Integral` value. .. function:: ulp(x) From a930062d257b066705c9a681aa6c7f0f342dea11 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 2 Apr 2022 15:59:41 -0700 Subject: [PATCH 026/237] [3.10] Document func parameter of locale.atof (GH-18183) (GH-32262) The second parameter (named `func`) has been present since the `locale` module was introduced in eef1d4e8b1, but has never been documented. This commit updates the documentation for `locale.atof` to clarify the behavior of the function and how the `func` parameter is used. Signed-off-by: Kevin Locke (cherry picked from commit 208da6d508bb2683732151f4ae288dfc8001267c) Co-authored-by: Kevin Locke --- Doc/library/locale.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/locale.rst b/Doc/library/locale.rst index 60d0c59d017c73..dd14a379b0c6cc 100644 --- a/Doc/library/locale.rst +++ b/Doc/library/locale.rst @@ -435,10 +435,10 @@ The :mod:`locale` module defines the following exception and functions: .. versionadded:: 3.10 -.. function:: atof(string) +.. function:: atof(string, func=float) - Converts a string to a floating point number, following the :const:`LC_NUMERIC` - settings. + Converts a string to a number, following the :const:`LC_NUMERIC` settings, + by calling *func* on the result of calling :func:`delocalize` on *string*. .. function:: atoi(string) From 11f5fd1135065908c281ddfe767daa357c61e598 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 2 Apr 2022 16:00:51 -0700 Subject: [PATCH 027/237] [3.10] More minor fixes to C API docs (GH-31525) (GH-32258) * wording fixes in type.rst * grammar and punctuation in sys.rst * set: grammar fixes * structures: capitalization fix * grammar fixes for sequence * objects: point to Py_TYPE instead of direct object access * numbers: add more explicit Python equivalences * method: add missing period * memory: grammar fix * mapping: grammar fixes * long: grammar fix * iter: fix grammar for PyAIter_Check * init: grammar fix. (cherry picked from commit 897bc6f9282238d5fb32d232ab62d30675244736) Co-authored-by: Jelle Zijlstra --- Doc/c-api/init.rst | 2 +- Doc/c-api/iter.rst | 4 ++-- Doc/c-api/long.rst | 2 +- Doc/c-api/mapping.rst | 6 +++--- Doc/c-api/memory.rst | 2 +- Doc/c-api/method.rst | 2 +- Doc/c-api/number.rst | 9 +++++---- Doc/c-api/object.rst | 4 ++-- Doc/c-api/sequence.rst | 10 +++++----- Doc/c-api/set.rst | 6 +++--- Doc/c-api/structures.rst | 2 +- Doc/c-api/sys.rst | 6 +++--- Doc/c-api/type.rst | 2 +- 13 files changed, 29 insertions(+), 28 deletions(-) diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index 9ac3039d02ec38..a5227904460017 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -1725,7 +1725,7 @@ is not possible due to its implementation being opaque at build time. argument is `NULL`. .. note:: - A freed key becomes a dangling pointer, you should reset the key to + A freed key becomes a dangling pointer. You should reset the key to `NULL`. diff --git a/Doc/c-api/iter.rst b/Doc/c-api/iter.rst index 3e388bb917a029..434d2021cea8e6 100644 --- a/Doc/c-api/iter.rst +++ b/Doc/c-api/iter.rst @@ -14,8 +14,8 @@ There are two functions specifically for working with iterators. .. c:function:: int PyAIter_Check(PyObject *o) - Returns non-zero if the object 'obj' provides :class:`AsyncIterator` - protocols, and ``0`` otherwise. This function always succeeds. + Return non-zero if the object *o* provides the :class:`AsyncIterator` + protocol, and ``0`` otherwise. This function always succeeds. .. versionadded:: 3.10 diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst index 4201490286b82f..620344e71373b2 100644 --- a/Doc/c-api/long.rst +++ b/Doc/c-api/long.rst @@ -41,7 +41,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. Return a new :c:type:`PyLongObject` object from *v*, or ``NULL`` on failure. The current implementation keeps an array of integer objects for all integers - between ``-5`` and ``256``, when you create an int in that range you actually + between ``-5`` and ``256``. When you create an int in that range you actually just get back a reference to the existing object. diff --git a/Doc/c-api/mapping.rst b/Doc/c-api/mapping.rst index 682160d1475c1c..3c9d282c6d0ab0 100644 --- a/Doc/c-api/mapping.rst +++ b/Doc/c-api/mapping.rst @@ -11,10 +11,10 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and .. c:function:: int PyMapping_Check(PyObject *o) - Return ``1`` if the object provides mapping protocol or supports slicing, + Return ``1`` if the object provides the mapping protocol or supports slicing, and ``0`` otherwise. Note that it returns ``1`` for Python classes with - a :meth:`__getitem__` method since in general case it is impossible to - determine what type of keys it supports. This function always succeeds. + a :meth:`__getitem__` method, since in general it is impossible to + determine what type of keys the class supports. This function always succeeds. .. c:function:: Py_ssize_t PyMapping_Size(PyObject *o) diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index 0746d9ac52a7bc..ced7ca79ca5900 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -306,7 +306,7 @@ memory from the Python heap. .. note:: There is no guarantee that the memory returned by these allocators can be - successfully casted to a Python object when intercepting the allocating + successfully cast to a Python object when intercepting the allocating functions in this domain by the methods described in the :ref:`Customize Memory Allocators ` section. diff --git a/Doc/c-api/method.rst b/Doc/c-api/method.rst index 23852251dfe020..6e7e1e21aa93f2 100644 --- a/Doc/c-api/method.rst +++ b/Doc/c-api/method.rst @@ -27,7 +27,7 @@ to bind a :c:data:`PyCFunction` to a class object. It replaces the former call .. c:function:: PyObject* PyInstanceMethod_New(PyObject *func) - Return a new instance method object, with *func* being any callable object + Return a new instance method object, with *func* being any callable object. *func* is the function that will be called when the instance method is called. diff --git a/Doc/c-api/number.rst b/Doc/c-api/number.rst index 37979bb506bcfa..11c9c67d36a678 100644 --- a/Doc/c-api/number.rst +++ b/Doc/c-api/number.rst @@ -44,7 +44,7 @@ Number Protocol .. c:function:: PyObject* PyNumber_FloorDivide(PyObject *o1, PyObject *o2) Return the floor of *o1* divided by *o2*, or ``NULL`` on failure. This is - equivalent to the "classic" division of integers. + the equivalent of the Python expression ``o1 // o2``. .. c:function:: PyObject* PyNumber_TrueDivide(PyObject *o1, PyObject *o2) @@ -53,7 +53,7 @@ Number Protocol *o2*, or ``NULL`` on failure. The return value is "approximate" because binary floating point numbers are approximate; it is not possible to represent all real numbers in base two. This function can return a floating point value when - passed two integers. + passed two integers. This is the equivalent of the Python expression ``o1 / o2``. .. c:function:: PyObject* PyNumber_Remainder(PyObject *o1, PyObject *o2) @@ -180,6 +180,7 @@ Number Protocol floating point numbers are approximate; it is not possible to represent all real numbers in base two. This function can return a floating point value when passed two integers. The operation is done *in-place* when *o1* supports it. + This is the equivalent of the Python statement ``o1 /= o2``. .. c:function:: PyObject* PyNumber_InPlaceRemainder(PyObject *o1, PyObject *o2) @@ -285,6 +286,6 @@ Number Protocol .. c:function:: int PyIndex_Check(PyObject *o) - Returns ``1`` if *o* is an index integer (has the nb_index slot of the - tp_as_number structure filled in), and ``0`` otherwise. + Returns ``1`` if *o* is an index integer (has the ``nb_index`` slot of the + ``tp_as_number`` structure filled in), and ``0`` otherwise. This function always succeeds. diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index 41a3affcf9842a..9dcfd769c64a05 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -93,7 +93,7 @@ Object Protocol return ``0`` on success. This is the equivalent of the Python statement ``o.attr_name = v``. - If *v* is ``NULL``, the attribute is deleted, however this feature is + If *v* is ``NULL``, the attribute is deleted, but this feature is deprecated in favour of using :c:func:`PyObject_DelAttrString`. @@ -291,7 +291,7 @@ Object Protocol of object *o*. On failure, raises :exc:`SystemError` and returns ``NULL``. This is equivalent to the Python expression ``type(o)``. This function increments the reference count of the return value. There's really no reason to use this - function instead of the common expression ``o->ob_type``, which returns a + function instead of the :c:func:`Py_TYPE()` function, which returns a pointer of type :c:type:`PyTypeObject*`, except when the incremented reference count is needed. diff --git a/Doc/c-api/sequence.rst b/Doc/c-api/sequence.rst index 65818859041179..c78d273f9f149f 100644 --- a/Doc/c-api/sequence.rst +++ b/Doc/c-api/sequence.rst @@ -8,10 +8,10 @@ Sequence Protocol .. c:function:: int PySequence_Check(PyObject *o) - Return ``1`` if the object provides sequence protocol, and ``0`` otherwise. + Return ``1`` if the object provides the sequence protocol, and ``0`` otherwise. Note that it returns ``1`` for Python classes with a :meth:`__getitem__` - method unless they are :class:`dict` subclasses since in general case it - is impossible to determine what the type of keys it supports. This + method, unless they are :class:`dict` subclasses, since in general it + is impossible to determine what type of keys the class supports. This function always succeeds. @@ -69,7 +69,7 @@ Sequence Protocol is the equivalent of the Python statement ``o[i] = v``. This function *does not* steal a reference to *v*. - If *v* is ``NULL``, the element is deleted, however this feature is + If *v* is ``NULL``, the element is deleted, but this feature is deprecated in favour of using :c:func:`PySequence_DelItem`. @@ -147,7 +147,7 @@ Sequence Protocol Returns the length of *o*, assuming that *o* was returned by :c:func:`PySequence_Fast` and that *o* is not ``NULL``. The size can also be - gotten by calling :c:func:`PySequence_Size` on *o*, but + retrieved by calling :c:func:`PySequence_Size` on *o*, but :c:func:`PySequence_Fast_GET_SIZE` is faster because it can assume *o* is a list or tuple. diff --git a/Doc/c-api/set.rst b/Doc/c-api/set.rst index eca19c4d816474..f0d905bae8ae44 100644 --- a/Doc/c-api/set.rst +++ b/Doc/c-api/set.rst @@ -13,7 +13,7 @@ Set Objects object: frozenset This section details the public API for :class:`set` and :class:`frozenset` -objects. Any functionality not listed below is best accessed using the either +objects. Any functionality not listed below is best accessed using either the abstract object protocol (including :c:func:`PyObject_CallMethod`, :c:func:`PyObject_RichCompareBool`, :c:func:`PyObject_Hash`, :c:func:`PyObject_Repr`, :c:func:`PyObject_IsTrue`, :c:func:`PyObject_Print`, and @@ -31,7 +31,7 @@ the abstract object protocol (including :c:func:`PyObject_CallMethod`, in that it is a fixed size for small sets (much like tuple storage) and will point to a separate, variable sized block of memory for medium and large sized sets (much like list storage). None of the fields of this structure should be - considered public and are subject to change. All access should be done through + considered public and all are subject to change. All access should be done through the documented API rather than by manipulating the values in the structure. @@ -131,7 +131,7 @@ or :class:`frozenset` or instances of their subtypes. .. c:function:: int PySet_Add(PyObject *set, PyObject *key) Add *key* to a :class:`set` instance. Also works with :class:`frozenset` - instances (like :c:func:`PyTuple_SetItem` it can be used to fill-in the values + instances (like :c:func:`PyTuple_SetItem` it can be used to fill in the values of brand new frozensets before they are exposed to other code). Return ``0`` on success or ``-1`` on failure. Raise a :exc:`TypeError` if the *key* is unhashable. Raise a :exc:`MemoryError` if there is no room to grow. Raise a diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index 05c54ccc8dab59..839c889a6c8a77 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -494,7 +494,7 @@ Accessing attributes of extension types +=============+==================+===================================+ | name | const char \* | attribute name | +-------------+------------------+-----------------------------------+ - | get | getter | C Function to get the attribute | + | get | getter | C function to get the attribute | +-------------+------------------+-----------------------------------+ | set | setter | optional C function to set or | | | | delete the attribute, if omitted | diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst index 97717f5fc19230..350d4e1de41ba7 100644 --- a/Doc/c-api/sys.rst +++ b/Doc/c-api/sys.rst @@ -177,7 +177,7 @@ Operating System Utilities Return a pointer to a newly allocated byte string, use :c:func:`PyMem_Free` to free the memory. Return ``NULL`` on encoding error or memory allocation - error + error. If error_pos is not ``NULL``, ``*error_pos`` is set to ``(size_t)-1`` on success, or set to the index of the invalid character on encoding error. @@ -207,7 +207,7 @@ Operating System Utilities .. versionchanged:: 3.8 The function now uses the UTF-8 encoding on Windows if - :c:data:`Py_LegacyWindowsFSEncodingFlag` is zero; + :c:data:`Py_LegacyWindowsFSEncodingFlag` is zero. .. _systemfunctions: @@ -338,7 +338,7 @@ accessible to C code. They all work with the current interpreter thread's .. c:function:: int PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) Append the callable *hook* to the list of active auditing hooks. - Return zero for success + Return zero on success and non-zero on failure. If the runtime has been initialized, also set an error on failure. Hooks added through this API are called for all interpreters created by the runtime. diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index c472e8df9cf431..01d00bede544d7 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -272,7 +272,7 @@ The following functions and structs are used to create .. versionchanged:: 3.9 - Slots in :c:type:`PyBufferProcs` in may be set in the unlimited API. + Slots in :c:type:`PyBufferProcs` may be set in the unlimited API. .. c:member:: void *PyType_Slot.pfunc From ce6af314ca8529d5ed0f307deb9c33029a69f4cb Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 2 Apr 2022 17:40:55 -0700 Subject: [PATCH 028/237] bpo-24563: Link encoding names to encoding declarations (GH-32274) (cherry picked from commit 01be5d6446abbdd95d0c18bd19a58a62b05568d8) Co-authored-by: Terry Jan Reedy --- Doc/reference/lexical_analysis.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index 21ad3731a32467..d9e2cead958c95 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -101,12 +101,11 @@ addition, if the first bytes of the file are the UTF-8 byte-order mark (``b'\xef\xbb\xbf'``), the declared file encoding is UTF-8 (this is supported, among others, by Microsoft's :program:`notepad`). -If an encoding is declared, the encoding name must be recognized by Python. The +If an encoding is declared, the encoding name must be recognized by Python +(see :ref:`standard-encodings`). The encoding is used for all lexical analysis, including string literals, comments and identifiers. -.. XXX there should be a list of supported encodings. - .. _explicit-joining: From a5c90784be0bf70287bac4195573e85e956c2332 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 2 Apr 2022 20:05:11 -0700 Subject: [PATCH 029/237] Language reference: Remove duplicated text about iterable unpacking (GH-25212) (cherry picked from commit 4f5d56f8f33196f5ed8ffad0ab2f012afda2f9b3) Co-authored-by: Jiashuo Li <4003950+jiasli@users.noreply.github.com> --- Doc/reference/simple_stmts.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst index 92dfcb0461e60c..8dfc01db263f5c 100644 --- a/Doc/reference/simple_stmts.rst +++ b/Doc/reference/simple_stmts.rst @@ -124,9 +124,7 @@ square brackets, is recursively defined as follows. * If the target list is a single target with no trailing comma, optionally in parentheses, the object is assigned to that target. -* Else: The object must be an iterable with the same number of - items as there are targets in the target list, and the items are assigned, - from left to right, to the corresponding targets. +* Else: * If the target list contains one target prefixed with an asterisk, called a "starred" target: The object must be an iterable with at least as many items From 470dfe20cb6e741c42c52619e122fc218e27aebd Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 3 Apr 2022 12:27:32 -0700 Subject: [PATCH 030/237] bpo-47205: Skip error check of sched_get/setaffinity on FreeBSD (GH-32285) (cherry picked from commit b82cdd1dac9a9be52051abd90a1ce69236ac41f4) Co-authored-by: Christian Heimes --- Lib/test/test_posix.py | 8 ++++++-- .../next/Tests/2022-04-03-14-38-21.bpo-47205.hbbTnh.rst | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2022-04-03-14-38-21.bpo-47205.hbbTnh.rst diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 974edd766cc809..701543bb6ac662 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -1179,7 +1179,9 @@ def test_sched_getaffinity(self): mask = posix.sched_getaffinity(0) self.assertIsInstance(mask, set) self.assertGreaterEqual(len(mask), 1) - self.assertRaises(OSError, posix.sched_getaffinity, -1) + if not sys.platform.startswith("freebsd"): + # bpo-47205: does not raise OSError on FreeBSD + self.assertRaises(OSError, posix.sched_getaffinity, -1) for cpu in mask: self.assertIsInstance(cpu, int) self.assertGreaterEqual(cpu, 0) @@ -1197,7 +1199,9 @@ def test_sched_setaffinity(self): self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-10]) self.assertRaises(ValueError, posix.sched_setaffinity, 0, map(int, "0X")) self.assertRaises(OverflowError, posix.sched_setaffinity, 0, [1<<128]) - self.assertRaises(OSError, posix.sched_setaffinity, -1, mask) + if not sys.platform.startswith("freebsd"): + # bpo-47205: does not raise OSError on FreeBSD + self.assertRaises(OSError, posix.sched_setaffinity, -1, mask) def test_rtld_constants(self): # check presence of major RTLD_* constants diff --git a/Misc/NEWS.d/next/Tests/2022-04-03-14-38-21.bpo-47205.hbbTnh.rst b/Misc/NEWS.d/next/Tests/2022-04-03-14-38-21.bpo-47205.hbbTnh.rst new file mode 100644 index 00000000000000..35fd94421326ee --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-04-03-14-38-21.bpo-47205.hbbTnh.rst @@ -0,0 +1,2 @@ +Skip test for :func:`~os.sched_getaffinity` and +:func:`~os.sched_setaffinity` error case on FreeBSD. From a331d0f627406d621fa8ef1a1407f2c8a4cee4b5 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 3 Apr 2022 15:49:52 -0700 Subject: [PATCH 031/237] Follow PEP-8 guidelines in tutorial for standard library (GH-26127) (cherry picked from commit 6db2db91b96aaa1270c200ec931a2250fe2799c7) Co-authored-by: Bob Kline --- Doc/tutorial/stdlib.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Doc/tutorial/stdlib.rst b/Doc/tutorial/stdlib.rst index ac16160b234394..aac1ae3a8a6b42 100644 --- a/Doc/tutorial/stdlib.rst +++ b/Doc/tutorial/stdlib.rst @@ -78,8 +78,9 @@ and an optional number of lines to be displayed:: import argparse - parser = argparse.ArgumentParser(prog = 'top', - description = 'Show top lines from each file') + parser = argparse.ArgumentParser( + prog='top', + description='Show top lines from each file') parser.add_argument('filenames', nargs='+') parser.add_argument('-l', '--lines', type=int, default=10) args = parser.parse_args() From 29ffac2d39f7e45834880e359e1bda9a4152f016 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 4 Apr 2022 08:58:44 -0700 Subject: [PATCH 032/237] Demonstrate `py --list` in the quickstart section of the Windows doc page (GH-29383) (cherry picked from commit 1ecfe3d5ae4ddec4e73a6cfc93fed6df43fe0be5) Co-authored-by: Christian Clauss --- Doc/using/windows.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index cad7f69806d035..2c348aff12a624 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -710,6 +710,12 @@ If you see the following error, you do not have the launcher installed: Per-user installations of Python do not add the launcher to :envvar:`PATH` unless the option was selected on installation. +:: + + py --list + +You should see the currently installed versions of Python. + Virtual environments ^^^^^^^^^^^^^^^^^^^^ From 6b4b892e0962a7050c5064133c59955691f9776c Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 4 Apr 2022 10:43:38 -0700 Subject: [PATCH 033/237] bpo-46484:Add test for Calendar.iterweekdays (GH-30825) (cherry picked from commit 48269ea9fdbc5804f80962364f95e69097c417ba) Co-authored-by: 180909 <734461790@qq.com> --- Lib/test/test_calendar.py | 8 ++++++++ Misc/ACKS | 1 + 2 files changed, 9 insertions(+) diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index 39094ad6fd9abd..5ae2b66ff3b5fe 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -619,6 +619,14 @@ def test_itermonthdays2(self): self.assertEqual(days[0][1], firstweekday) self.assertEqual(days[-1][1], (firstweekday - 1) % 7) + def test_iterweekdays(self): + week0 = list(range(7)) + for firstweekday in range(7): + cal = calendar.Calendar(firstweekday) + week = list(cal.iterweekdays()) + expected = week0[firstweekday:] + week0[:firstweekday] + self.assertEqual(week, expected) + class MonthCalendarTestCase(unittest.TestCase): def setUp(self): diff --git a/Misc/ACKS b/Misc/ACKS index 1f1364e4f0bb87..ab4a037d298b5c 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1875,6 +1875,7 @@ Jacob Walls Kevin Walzer Rodrigo Steinmuller Wanderley Dingyuan Wang +Jiahua Wang Ke Wang Liang-Bo Wang Greg Ward From 3fa800d7a7a405f51e0e8c9b7dac2f2a75c17bb4 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 4 Apr 2022 19:30:06 -0700 Subject: [PATCH 034/237] bpo-41233: Add links to errnos referenced in exceptions docs (GH-21380) Co-authored-by: Andrew Kuchling Co-authored-by: Jelle Zijlstra (cherry picked from commit a74892cb2168d249d9a8c53fad605a5def9b41d4) Co-authored-by: yyyyyyyan <24644216+yyyyyyyan@users.noreply.github.com> --- Doc/library/errno.rst | 61 ++++++++++++------- Doc/library/exceptions.rst | 28 ++++----- Misc/ACKS | 1 + .../2020-07-07-22-54-51.bpo-41233.lyUJ8L.rst | 1 + 4 files changed, 54 insertions(+), 37 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2020-07-07-22-54-51.bpo-41233.lyUJ8L.rst diff --git a/Doc/library/errno.rst b/Doc/library/errno.rst index 1cbd51c582c0cf..c87da091bf84f6 100644 --- a/Doc/library/errno.rst +++ b/Doc/library/errno.rst @@ -8,7 +8,7 @@ This module makes available standard ``errno`` system symbols. The value of each symbol is the corresponding integer value. The names and descriptions are -borrowed from :file:`linux/include/errno.h`, which should be pretty +borrowed from :file:`linux/include/errno.h`, which should be all-inclusive. @@ -27,25 +27,26 @@ defined by the module. The specific list of defined symbols is available as .. data:: EPERM - Operation not permitted + Operation not permitted. This error is mapped to the exception + :exc:`PermissionError`. .. data:: ENOENT - No such file or directory + No such file or directory. This error is mapped to the exception + :exc:`FileNotFoundError`. .. data:: ESRCH - No such process + No such process. This error is mapped to the exception + :exc:`ProcessLookupError`. .. data:: EINTR - Interrupted system call. - - .. seealso:: - This error is mapped to the exception :exc:`InterruptedError`. + Interrupted system call. This error is mapped to the exception + :exc:`InterruptedError`. .. data:: EIO @@ -75,12 +76,13 @@ defined by the module. The specific list of defined symbols is available as .. data:: ECHILD - No child processes + No child processes. This error is mapped to the exception + :exc:`ChildProcessError`. .. data:: EAGAIN - Try again + Try again. This error is mapped to the exception :exc:`BlockingIOError`. .. data:: ENOMEM @@ -90,7 +92,8 @@ defined by the module. The specific list of defined symbols is available as .. data:: EACCES - Permission denied + Permission denied. This error is mapped to the exception + :exc:`PermissionError`. .. data:: EFAULT @@ -110,7 +113,8 @@ defined by the module. The specific list of defined symbols is available as .. data:: EEXIST - File exists + File exists. This error is mapped to the exception + :exc:`FileExistsError`. .. data:: EXDEV @@ -125,12 +129,14 @@ defined by the module. The specific list of defined symbols is available as .. data:: ENOTDIR - Not a directory + Not a directory. This error is mapped to the exception + :exc:`NotADirectoryError`. .. data:: EISDIR - Is a directory + Is a directory. This error is mapped to the exception + :exc:`IsADirectoryError`. .. data:: EINVAL @@ -185,7 +191,8 @@ defined by the module. The specific list of defined symbols is available as .. data:: EPIPE - Broken pipe + Broken pipe. This error is mapped to the exception + :exc:`BrokenPipeError`. .. data:: EDOM @@ -230,7 +237,8 @@ defined by the module. The specific list of defined symbols is available as .. data:: EWOULDBLOCK - Operation would block + Operation would block. This error is mapped to the exception + :exc:`BlockingIOError`. .. data:: ENOMSG @@ -540,12 +548,14 @@ defined by the module. The specific list of defined symbols is available as .. data:: ECONNABORTED - Software caused connection abort + Software caused connection abort. This error is mapped to the + exception :exc:`ConnectionAbortedError`. .. data:: ECONNRESET - Connection reset by peer + Connection reset by peer. This error is mapped to the exception + :exc:`ConnectionResetError`. .. data:: ENOBUFS @@ -565,7 +575,8 @@ defined by the module. The specific list of defined symbols is available as .. data:: ESHUTDOWN - Cannot send after transport endpoint shutdown + Cannot send after transport endpoint shutdown. This error is mapped + to the exception :exc:`BrokenPipeError`. .. data:: ETOOMANYREFS @@ -575,12 +586,14 @@ defined by the module. The specific list of defined symbols is available as .. data:: ETIMEDOUT - Connection timed out + Connection timed out. This error is mapped to the exception + :exc:`TimeoutError`. .. data:: ECONNREFUSED - Connection refused + Connection refused. This error is mapped to the exception + :exc:`ConnectionRefusedError`. .. data:: EHOSTDOWN @@ -595,12 +608,14 @@ defined by the module. The specific list of defined symbols is available as .. data:: EALREADY - Operation already in progress + Operation already in progress. This error is mapped to the + exception :exc:`BlockingIOError`. .. data:: EINPROGRESS - Operation now in progress + Operation now in progress. This error is mapped to the exception + :exc:`BlockingIOError`. .. data:: ESTALE diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst index 50a3ff3452c99e..9a3c92554df632 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -644,8 +644,8 @@ depending on the system error code. Raised when an operation would block on an object (e.g. socket) set for non-blocking operation. - Corresponds to :c:data:`errno` ``EAGAIN``, ``EALREADY``, - ``EWOULDBLOCK`` and ``EINPROGRESS``. + Corresponds to :c:data:`errno` :py:data:`~errno.EAGAIN`, :py:data:`~errno.EALREADY`, + :py:data:`~errno.EWOULDBLOCK` and :py:data:`~errno.EINPROGRESS`. In addition to those of :exc:`OSError`, :exc:`BlockingIOError` can have one more attribute: @@ -659,7 +659,7 @@ depending on the system error code. .. exception:: ChildProcessError Raised when an operation on a child process failed. - Corresponds to :c:data:`errno` ``ECHILD``. + Corresponds to :c:data:`errno` :py:data:`~errno.ECHILD`. .. exception:: ConnectionError @@ -673,35 +673,35 @@ depending on the system error code. A subclass of :exc:`ConnectionError`, raised when trying to write on a pipe while the other end has been closed, or trying to write on a socket which has been shutdown for writing. - Corresponds to :c:data:`errno` ``EPIPE`` and ``ESHUTDOWN``. + Corresponds to :c:data:`errno` :py:data:`~errno.EPIPE` and :py:data:`~errno.ESHUTDOWN`. .. exception:: ConnectionAbortedError A subclass of :exc:`ConnectionError`, raised when a connection attempt is aborted by the peer. - Corresponds to :c:data:`errno` ``ECONNABORTED``. + Corresponds to :c:data:`errno` :py:data:`~errno.ECONNABORTED`. .. exception:: ConnectionRefusedError A subclass of :exc:`ConnectionError`, raised when a connection attempt is refused by the peer. - Corresponds to :c:data:`errno` ``ECONNREFUSED``. + Corresponds to :c:data:`errno` :py:data:`~errno.ECONNREFUSED`. .. exception:: ConnectionResetError A subclass of :exc:`ConnectionError`, raised when a connection is reset by the peer. - Corresponds to :c:data:`errno` ``ECONNRESET``. + Corresponds to :c:data:`errno` :py:data:`~errno.ECONNRESET`. .. exception:: FileExistsError Raised when trying to create a file or directory which already exists. - Corresponds to :c:data:`errno` ``EEXIST``. + Corresponds to :c:data:`errno` :py:data:`~errno.EEXIST`. .. exception:: FileNotFoundError Raised when a file or directory is requested but doesn't exist. - Corresponds to :c:data:`errno` ``ENOENT``. + Corresponds to :c:data:`errno` :py:data:`~errno.ENOENT`. .. exception:: InterruptedError @@ -717,7 +717,7 @@ depending on the system error code. Raised when a file operation (such as :func:`os.remove`) is requested on a directory. - Corresponds to :c:data:`errno` ``EISDIR``. + Corresponds to :c:data:`errno` :py:data:`~errno.EISDIR`. .. exception:: NotADirectoryError @@ -725,23 +725,23 @@ depending on the system error code. something which is not a directory. On most POSIX platforms, it may also be raised if an operation attempts to open or traverse a non-directory file as if it were a directory. - Corresponds to :c:data:`errno` ``ENOTDIR``. + Corresponds to :c:data:`errno` :py:data:`~errno.ENOTDIR`. .. exception:: PermissionError Raised when trying to run an operation without the adequate access rights - for example filesystem permissions. - Corresponds to :c:data:`errno` ``EACCES`` and ``EPERM``. + Corresponds to :c:data:`errno` :py:data:`~errno.EACCES` and :py:data:`~errno.EPERM`. .. exception:: ProcessLookupError Raised when a given process doesn't exist. - Corresponds to :c:data:`errno` ``ESRCH``. + Corresponds to :c:data:`errno` :py:data:`~errno.ESRCH`. .. exception:: TimeoutError Raised when a system function timed out at the system level. - Corresponds to :c:data:`errno` ``ETIMEDOUT``. + Corresponds to :c:data:`errno` :py:data:`~errno.ETIMEDOUT`. .. versionadded:: 3.3 All the above :exc:`OSError` subclasses were added. diff --git a/Misc/ACKS b/Misc/ACKS index ab4a037d298b5c..c6abfac531cbee 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1291,6 +1291,7 @@ Ken Jin Ooi Piet van Oostrum Tomas Oppelstrup Jason Orendorff +Yan "yyyyyyyan" Orestes Bastien Orivel orlnub123 Douglas Orr diff --git a/Misc/NEWS.d/next/Documentation/2020-07-07-22-54-51.bpo-41233.lyUJ8L.rst b/Misc/NEWS.d/next/Documentation/2020-07-07-22-54-51.bpo-41233.lyUJ8L.rst new file mode 100644 index 00000000000000..ea0643aa00ee0b --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-07-07-22-54-51.bpo-41233.lyUJ8L.rst @@ -0,0 +1 @@ +Link the errnos referenced in ``Doc/library/exceptions.rst`` to their respective section in ``Doc/library/errno.rst``, and vice versa. Previously this was only done for EINTR and InterruptedError. Patch by Yan "yyyyyyyan" Orestes. From f502dadb332f911fa3b6c531bbc5065795cca242 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 4 Apr 2022 19:56:29 -0700 Subject: [PATCH 035/237] bpo-47007: [doc] `str` special method lookup (GH-31863) Clarify the `str()` docs to point out that `object.__str__()` follows special method lookup. Co-authored-by: Jelle Zijlstra (cherry picked from commit bb86d1d9fbd1888524e04475383f4ea764277f67) Co-authored-by: Vanshaj Singhania <8797467+itsvs@users.noreply.github.com> --- Doc/library/stdtypes.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index b330335773103b..28082b42d7923b 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -1479,7 +1479,8 @@ multiple fragments. depends on whether *encoding* or *errors* is given, as follows. If neither *encoding* nor *errors* is given, ``str(object)`` returns - :meth:`object.__str__() `, which is the "informal" or nicely + :meth:`type(object).__str__(object) `, + which is the "informal" or nicely printable string representation of *object*. For string objects, this is the string itself. If *object* does not have a :meth:`~object.__str__` method, then :func:`str` falls back to returning From f4e711bb49881deb1f07a685878646cd5cdee50f Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 4 Apr 2022 19:57:22 -0700 Subject: [PATCH 036/237] bpo-45790: List macros in same order in which fields are described (GH-29529) Signed-off-by: Rodrigo Tobar Co-authored-by: Jelle Zijlstra (cherry picked from commit b275267aa7d44ec90fa435c9cb1610c549da745a) Co-authored-by: rtobar --- Doc/extending/newtypes_tutorial.rst | 4 ++-- .../Documentation/2021-11-12-11-03-55.bpo-45790.6yuhe8.rst | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2021-11-12-11-03-55.bpo-45790.6yuhe8.rst diff --git a/Doc/extending/newtypes_tutorial.rst b/Doc/extending/newtypes_tutorial.rst index 530e2c4d35f848..904915306f1f38 100644 --- a/Doc/extending/newtypes_tutorial.rst +++ b/Doc/extending/newtypes_tutorial.rst @@ -67,8 +67,8 @@ The first bit is:: This is what a Custom object will contain. ``PyObject_HEAD`` is mandatory at the start of each object struct and defines a field called ``ob_base`` of type :c:type:`PyObject`, containing a pointer to a type object and a -reference count (these can be accessed using the macros :c:macro:`Py_REFCNT` -and :c:macro:`Py_TYPE` respectively). The reason for the macro is to +reference count (these can be accessed using the macros :c:macro:`Py_TYPE` +and :c:macro:`Py_REFCNT` respectively). The reason for the macro is to abstract away the layout and to enable additional fields in :ref:`debug builds `. diff --git a/Misc/NEWS.d/next/Documentation/2021-11-12-11-03-55.bpo-45790.6yuhe8.rst b/Misc/NEWS.d/next/Documentation/2021-11-12-11-03-55.bpo-45790.6yuhe8.rst new file mode 100644 index 00000000000000..41cf2cb91525f4 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2021-11-12-11-03-55.bpo-45790.6yuhe8.rst @@ -0,0 +1,2 @@ +Adjust inaccurate phrasing in :doc:`../extending/newtypes_tutorial` about the +``ob_base`` field and the macros used to access its contents. From d95e072c419e40b0fb67b8cc8a84087c8a0276ee Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 4 Apr 2022 20:08:17 -0700 Subject: [PATCH 037/237] bpo-32658: Regex docs: Fix metacharacter reference (GH-32230) Co-authored-by: Jelle Zijlstra (cherry picked from commit 43571a3eea8b5931769376daf4bdad1c9184ae0d) Co-authored-by: Mike cm --- Doc/howto/regex.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/regex.rst b/Doc/howto/regex.rst index d574c3736b1cb7..c4ebbd311e0fe3 100644 --- a/Doc/howto/regex.rst +++ b/Doc/howto/regex.rst @@ -89,7 +89,7 @@ is the same as ``[a-c]``, which uses a range to express the same set of characters. If you wanted to match only lowercase letters, your RE would be ``[a-z]``. -Metacharacters are not active inside classes. For example, ``[akm$]`` will +Metacharacters (except ``\``) are not active inside classes. For example, ``[akm$]`` will match any of the characters ``'a'``, ``'k'``, ``'m'``, or ``'$'``; ``'$'`` is usually a metacharacter, but inside a character class it's stripped of its special nature. From 97151e1e3a683d7b5d196e66b8a3482896eb8c9b Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 4 Apr 2022 20:09:45 -0700 Subject: [PATCH 038/237] crypt docs: Fix references to `methods` attr (GH-26806) Co-authored-by: Jelle Zijlstra (cherry picked from commit cae0f5d3dad6db0d13690e5952ae2015ad8b3a05) Co-authored-by: andrei kulakov --- Doc/library/crypt.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Doc/library/crypt.rst b/Doc/library/crypt.rst index 73df87ca0db8d1..3189ece048a26e 100644 --- a/Doc/library/crypt.rst +++ b/Doc/library/crypt.rst @@ -96,8 +96,7 @@ The :mod:`crypt` module defines the following functions: :func:`mksalt`, one of the ``crypt.METHOD_*`` values (though not all may be available on all platforms), or a full encrypted password including salt, as returned by this function. If *salt* is not - provided, the strongest method will be used (as returned by - :func:`methods`). + provided, the strongest method available in :attr:`methods` will be used. Checking a password is usually done by passing the plain-text password as *word* and the full results of a previous :func:`crypt` call, @@ -125,8 +124,8 @@ The :mod:`crypt` module defines the following functions: .. function:: mksalt(method=None, *, rounds=None) Return a randomly generated salt of the specified method. If no - *method* is given, the strongest method available as returned by - :func:`methods` is used. + *method* is given, the strongest method available in :attr:`methods` is + used. The return value is a string suitable for passing as the *salt* argument to :func:`crypt`. From 857cf55cbdd65b7a9534dc35d89a19dfe8cbdba5 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 4 Apr 2022 20:16:16 -0700 Subject: [PATCH 039/237] bpo-40982: shutil docs: Remove outdated copytree() example (GH-24778) It is not preferable to keep a copy of the implementation in the docs. (cherry picked from commit e06f920c5bc6e9fad29082ba0d84043722806e17) Co-authored-by: Zackery Spytz --- Doc/library/shutil.rst | 37 +------------------------------------ 1 file changed, 1 insertion(+), 36 deletions(-) diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 11c67074921672..5f71049f918e0e 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -470,42 +470,7 @@ file then shutil will silently fallback on using less efficient copytree example ~~~~~~~~~~~~~~~~ -This example is the implementation of the :func:`copytree` function, described -above, with the docstring omitted. It demonstrates many of the other functions -provided by this module. :: - - def copytree(src, dst, symlinks=False): - names = os.listdir(src) - os.makedirs(dst) - errors = [] - for name in names: - srcname = os.path.join(src, name) - dstname = os.path.join(dst, name) - try: - if symlinks and os.path.islink(srcname): - linkto = os.readlink(srcname) - os.symlink(linkto, dstname) - elif os.path.isdir(srcname): - copytree(srcname, dstname, symlinks) - else: - copy2(srcname, dstname) - # XXX What about devices, sockets etc.? - except OSError as why: - errors.append((srcname, dstname, str(why))) - # catch the Error from the recursive copytree so that we can - # continue with other files - except Error as err: - errors.extend(err.args[0]) - try: - copystat(src, dst) - except OSError as why: - # can't copy file access times on Windows - if why.winerror is None: - errors.extend((src, dst, str(why))) - if errors: - raise Error(errors) - -Another example that uses the :func:`ignore_patterns` helper:: +An example that uses the :func:`ignore_patterns` helper:: from shutil import copytree, ignore_patterns From 94609e3192f15636c760a48c4c1c2c236fac3217 Mon Sep 17 00:00:00 2001 From: Matthieu Dartiailh Date: Tue, 5 Apr 2022 18:21:49 +0200 Subject: [PATCH 040/237] [3.10] Backport bpo-47212 (GH-32302) to Python 3.10 (GH-32334) (cherry picked from commit aa0f056a00c4bcaef83d729e042359ddae903382) # Conflicts: # Grammar/python.gram # Parser/action_helpers.c Automerge-Triggered-By: GH:pablogsal --- Grammar/python.gram | 6 +++--- Lib/test/test_exceptions.py | 11 ++++++++++- Lib/test/test_syntax.py | 7 +++++++ .../2022-04-05-11-29-21.bpo-47212.leF4pz.rst | 3 +++ Parser/parser.c | 6 +++--- Parser/pegen.c | 2 +- Parser/pegen.h | 1 + 7 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-04-05-11-29-21.bpo-47212.leF4pz.rst diff --git a/Grammar/python.gram b/Grammar/python.gram index 99e01355a582cf..84b9c9b82720b7 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -830,12 +830,12 @@ t_lookahead: '(' | '[' | '.' invalid_arguments: | a=args ',' '*' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "iterable argument unpacking follows keyword argument unpacking") } | a=expression b=for_if_clauses ',' [args | expression for_if_clauses] { - RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, PyPegen_last_item(b, comprehension_ty)->target, "Generator expression must be parenthesized") } + RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, _PyPegen_get_last_comprehension_item(PyPegen_last_item(b, comprehension_ty)), "Generator expression must be parenthesized") } | a=NAME b='=' expression for_if_clauses { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax. Maybe you meant '==' or ':=' instead of '='?")} | a=args b=for_if_clauses { _PyPegen_nonparen_genexp_in_call(p, a, b) } | args ',' a=expression b=for_if_clauses { - RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, asdl_seq_GET(b, b->size-1)->target, "Generator expression must be parenthesized") } + RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, _PyPegen_get_last_comprehension_item(PyPegen_last_item(b, comprehension_ty)), "Generator expression must be parenthesized") } | a=args ',' args { _PyPegen_arguments_parsing_error(p, a) } invalid_kwarg: | a[Token*]=('True'|'False'|'None') b='=' { @@ -975,7 +975,7 @@ invalid_finally_stmt: invalid_except_stmt_indent: | a='except' expression ['as' NAME ] ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after 'except' statement on line %d", a->lineno) } - | a='except' ':' NEWLINE !INDENT { RAISE_SYNTAX_ERROR("expected an indented block after except statement on line %d", a->lineno) } + | a='except' ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after 'except' statement on line %d", a->lineno) } invalid_match_stmt: | "match" subject_expr !':' { CHECK_VERSION(void*, 10, "Pattern matching is", RAISE_SYNTAX_ERROR("expected ':'") ) } | a="match" subject=subject_expr ':' NEWLINE !INDENT { diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 2bdd7214b0505b..d9ea8a4872d716 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -198,12 +198,17 @@ def ckmsg(src, msg, exception=SyntaxError): s = '''if True:\n print()\n\texec "mixed tabs and spaces"''' ckmsg(s, "inconsistent use of tabs and spaces in indentation", TabError) - def check(self, src, lineno, offset, encoding='utf-8'): + def check(self, src, lineno, offset, end_lineno=None, end_offset=None, encoding='utf-8'): with self.subTest(source=src, lineno=lineno, offset=offset): with self.assertRaises(SyntaxError) as cm: compile(src, '', 'exec') self.assertEqual(cm.exception.lineno, lineno) self.assertEqual(cm.exception.offset, offset) + if end_lineno is not None: + self.assertEqual(cm.exception.end_lineno, end_lineno) + if end_offset is not None: + self.assertEqual(cm.exception.end_offset, end_offset) + if cm.exception.text is not None: if not isinstance(src, str): src = src.decode(encoding, 'replace') @@ -235,6 +240,10 @@ def testSyntaxErrorOffset(self): check('match ...:\n case {**rest, "key": value}:\n ...', 2, 19) check("[a b c d e f]", 1, 2) check("for x yfff:", 1, 7) + check("f(a for a in b, c)", 1, 3, 1, 15) + check("f(a for a in b if a, c)", 1, 3, 1, 20) + check("f(a, b for b in c)", 1, 6, 1, 18) + check("f(a, b for b in c, d)", 1, 6, 1, 18) # Errors thrown by compile.c check('class foo:return 1', 1, 11) diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 09c0d5682a7e45..006374e7cd912c 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -1012,6 +1012,13 @@ Traceback (most recent call last): IndentationError: expected an indented block after 'try' statement on line 1 + >>> try: + ... something() + ... except: + ... pass + Traceback (most recent call last): + IndentationError: expected an indented block after 'except' statement on line 3 + >>> try: ... something() ... except A: diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-04-05-11-29-21.bpo-47212.leF4pz.rst b/Misc/NEWS.d/next/Core and Builtins/2022-04-05-11-29-21.bpo-47212.leF4pz.rst new file mode 100644 index 00000000000000..8f1f6b6cfbbb89 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-04-05-11-29-21.bpo-47212.leF4pz.rst @@ -0,0 +1,3 @@ +Raise :exc:`IndentationError` instead of :exc:`SyntaxError` for a bare +``except`` with no following indent. Improve :exc:`SyntaxError` locations for +an un-parenthesized generator used as arguments. Patch by Matthieu Dartiailh. diff --git a/Parser/parser.c b/Parser/parser.c index 3f73003b789732..862950018a3127 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -18419,7 +18419,7 @@ invalid_arguments_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses ',' [args | expression for_if_clauses]")); - _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , PyPegen_last_item ( b , comprehension_ty ) -> target , "Generator expression must be parenthesized" ); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , _PyPegen_get_last_comprehension_item ( PyPegen_last_item ( b , comprehension_ty ) ) , "Generator expression must be parenthesized" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -18512,7 +18512,7 @@ invalid_arguments_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args ',' expression for_if_clauses")); - _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , asdl_seq_GET ( b , b -> size - 1 ) -> target , "Generator expression must be parenthesized" ); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , _PyPegen_get_last_comprehension_item ( PyPegen_last_item ( b , comprehension_ty ) ) , "Generator expression must be parenthesized" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -20804,7 +20804,7 @@ invalid_except_stmt_indent_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ invalid_except_stmt_indent[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' ':' NEWLINE !INDENT")); - _res = RAISE_SYNTAX_ERROR ( "expected an indented block after except statement on line %d" , a -> lineno ); + _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'except' statement on line %d" , a -> lineno ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; diff --git a/Parser/pegen.c b/Parser/pegen.c index 90a6ab98cf42e9..c04824315c7a36 100644 --- a/Parser/pegen.c +++ b/Parser/pegen.c @@ -2568,7 +2568,7 @@ void *_PyPegen_arguments_parsing_error(Parser *p, expr_ty e) { } -static inline expr_ty +expr_ty _PyPegen_get_last_comprehension_item(comprehension_ty comprehension) { if (comprehension->ifs == NULL || asdl_seq_LEN(comprehension->ifs) == 0) { return comprehension->iter; diff --git a/Parser/pegen.h b/Parser/pegen.h index 0e5a057c1f1960..118fbc7b3b78a2 100644 --- a/Parser/pegen.h +++ b/Parser/pegen.h @@ -327,6 +327,7 @@ _RAISE_SYNTAX_ERROR_INVALID_TARGET(Parser *p, TARGETS_TYPE type, void *e) } void *_PyPegen_arguments_parsing_error(Parser *, expr_ty); +expr_ty _PyPegen_get_last_comprehension_item(comprehension_ty comprehension); void *_PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args, asdl_comprehension_seq *comprehensions); From 8bce3cb16df5b8ac06ac6b2cae177dd221780b2f Mon Sep 17 00:00:00 2001 From: Jeremy Kloth Date: Tue, 5 Apr 2022 17:36:18 -0600 Subject: [PATCH 041/237] bpo-47230: Silence compiler warnings on Windows from zlib 1.2.12 (GH-32337) (cherry picked from commit 944f09adfcc59f54432ac2947cf95f3465d90e1e) Co-authored-by: Jeremy Kloth --- PCbuild/pythoncore.vcxproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index c39ba3e1a9f412..3ba63587642d1a 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -499,7 +499,9 @@ - + + 4244 + From 3856b4995ec0e632d47b733cdecb5183ac830568 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 6 Apr 2022 08:30:01 -0700 Subject: [PATCH 042/237] bpo-47235: Note where a typo is intentional in code. (GH-32348) People keep popping up reporting these as typos in the docs despite being described as typos in the surrounding text. Hopefully a comment on the line itself makes it more obvious? Arguably some of the typo examples are not using the "right" typo as the "assret" one in particular is now detected by default due to how common it was in actual code. But I don't want to to typo chasing by changing these examples to be other not yet auto-detected typos as they still illustrate the point well enough. (cherry picked from commit ac1fb07b6ecb6b93446484f52894914e5199de63) Co-authored-by: Gregory P. Smith --- Doc/library/unittest.mock.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index 4d74f9cee84ee8..86a848edab8895 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -2550,7 +2550,7 @@ your assertion is gone: >>> mock = Mock(name='Thing', return_value=None) >>> mock(1, 2, 3) - >>> mock.assret_called_once_with(4, 5, 6) + >>> mock.assret_called_once_with(4, 5, 6) # Intentional typo! Your tests can pass silently and incorrectly because of the typo. @@ -2570,7 +2570,7 @@ attributes on the mock that exist on the real class: >>> from urllib import request >>> mock = Mock(spec=request.Request) - >>> mock.assret_called_with + >>> mock.assret_called_with # Intentional typo! Traceback (most recent call last): ... AttributeError: Mock object has no attribute 'assret_called_with' @@ -2582,7 +2582,7 @@ with any methods on the mock: >>> mock.has_data() - >>> mock.has_data.assret_called_with() + >>> mock.has_data.assret_called_with() # Intentional typo! Auto-speccing solves this problem. You can either pass ``autospec=True`` to :func:`patch` / :func:`patch.object` or use the :func:`create_autospec` function to create a @@ -2625,7 +2625,7 @@ any typos in our asserts will raise the correct error:: >>> req.add_header('spam', 'eggs') - >>> req.add_header.assret_called_with + >>> req.add_header.assret_called_with # Intentional typo! Traceback (most recent call last): ... AttributeError: Mock object has no attribute 'assret_called_with' From 80af26d25af5568229d31ecb2a8f1bf9702b7791 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Thu, 7 Apr 2022 01:00:26 +0700 Subject: [PATCH 043/237] [3.10] bpo-46769: Fix backticks in typing.rst to appease rstlint (GH-32374) * Use double backticks to appease rstlint * Update susp-ignored.csv --- Doc/library/typing.rst | 2 +- Doc/tools/susp-ignored.csv | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index ea0bcee81c50aa..36d637f3665092 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1158,7 +1158,7 @@ These are not used in annotations. They are building blocks for creating generic self.radius = radius # Use a type variable to show that the return type - # will always be an instance of whatever `cls` is + # will always be an instance of whatever ``cls`` is @classmethod def with_circumference(cls: type[C], circumference: float) -> C: """Create a circle with the specified circumference""" diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index 0a8d702f96bce2..d7d5b3547a9d9c 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -384,4 +384,4 @@ library/typing,,`,# Type of ``val`` is narrowed to ``str`` library/typing,,`,"# Else, type of ``val`` is narrowed to ``float``." library/typing,,`,# Type of ``val`` is narrowed to ``List[str]``. library/typing,,`,# Type of ``val`` remains as ``List[object]``. -library/typing,,`, # will always be an instance of whatever `cls` is +library/typing,,`, # will always be an instance of whatever ``cls`` is From 55abb0ef25d9ecabc6fe93cf0d38f19268b5859c Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 6 Apr 2022 17:50:04 -0700 Subject: [PATCH 044/237] stdtypes docs: fix typo (GH-32349) (GH-32370) (cherry picked from commit b33c4564aceeae8323bcb19167fbbd2d5f5002bc) Co-authored-by: Ian <40774387+isteptoe@users.noreply.github.com> --- Doc/library/stdtypes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 28082b42d7923b..f60e936089c232 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -3580,7 +3580,7 @@ The conversion types are: | | be used for Python2/3 code bases. | | +------------+-----------------------------------------------------+-------+ | ``'a'`` | Bytes (converts any Python object using | \(5) | -| | ``repr(obj).encode('ascii','backslashreplace)``). | | +| | ``repr(obj).encode('ascii', 'backslashreplace')``). | | +------------+-----------------------------------------------------+-------+ | ``'r'`` | ``'r'`` is an alias for ``'a'`` and should only | \(7) | | | be used for Python2/3 code bases. | | From 08bd308dd2500616f28415113c4bce52a8065138 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 6 Apr 2022 18:12:34 -0700 Subject: [PATCH 045/237] pkgutil docs: Link sys constants, add backticks (GH-32356) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Éric (cherry picked from commit 63bd72448a5af01206c2a9aec5f1ed1e903f1e12) Co-authored-by: Boris Verkhovskiy --- Doc/library/pkgutil.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/library/pkgutil.rst b/Doc/library/pkgutil.rst index 3b17b9a6219870..788a02dcb8922f 100644 --- a/Doc/library/pkgutil.rst +++ b/Doc/library/pkgutil.rst @@ -26,7 +26,7 @@ support. __path__ = extend_path(__path__, __name__) This will add to the package's ``__path__`` all subdirectories of directories - on ``sys.path`` named after the package. This is useful if one wants to + on :data:`sys.path` named after the package. This is useful if one wants to distribute different parts of a single logical package as multiple directories. @@ -128,9 +128,9 @@ support. Yield :term:`finder` objects for the given module name. - If fullname contains a '.', the finders will be for the package + If fullname contains a ``'.'``, the finders will be for the package containing fullname, otherwise they will be all registered top level - finders (i.e. those on both sys.meta_path and sys.path_hooks). + finders (i.e. those on both :data:`sys.meta_path` and :data:`sys.path_hooks`). If the named module is in a package, that package is imported as a side effect of invoking this function. @@ -145,7 +145,7 @@ support. .. function:: iter_modules(path=None, prefix='') Yields :class:`ModuleInfo` for all submodules on *path*, or, if - *path* is ``None``, all top-level modules on ``sys.path``. + *path* is ``None``, all top-level modules on :data:`sys.path`. *path* should be either ``None`` or a list of paths to look for modules in. From b217ba7371a780ad014e4ed5695ab8d0a2ea588e Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 6 Apr 2022 18:13:46 -0700 Subject: [PATCH 046/237] ssl docs: Fix typo (GH-32314) (cherry picked from commit 1da9c38fd352465fd3d1a00e64dc90444b421730) Co-authored-by: Frederick --- Doc/library/ssl.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 3531cc3413afa2..84abbaf935374c 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -1397,7 +1397,7 @@ SSL sockets also have the following additional methods and attributes: .. method:: SSLSocket.version() Return the actual SSL protocol version negotiated by the connection - as a string, or ``None`` is no secure connection is established. + as a string, or ``None`` if no secure connection is established. As of this writing, possible return values include ``"SSLv2"``, ``"SSLv3"``, ``"TLSv1"``, ``"TLSv1.1"`` and ``"TLSv1.2"``. Recent OpenSSL versions may define more return values. From ccac6312b9f9d8209646c85492920962fb5704ba Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 6 Apr 2022 18:52:51 -0700 Subject: [PATCH 047/237] doc: Link to `string.capwords` from `str.title` (GH-20913) Since `title()` mentions its own short-comings, it should also mention the library function which does not possess them. Co-authored-by: Jelle Zijlstra (cherry picked from commit b786d9ec52a2c2b0b6627be7fd4a3948c61fbdea) Co-authored-by: Eric Wieser --- Doc/library/stdtypes.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index f60e936089c232..77b2590860e32d 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2151,7 +2151,11 @@ expression support in the :mod:`re` module). >>> "they're bill's friends from the UK".title() "They'Re Bill'S Friends From The Uk" - A workaround for apostrophes can be constructed using regular expressions:: + The :func:`string.capwords` function does not have this problem, as it + splits words on spaces only. + + Alternatively, a workaround for apostrophes can be constructed using regular + expressions:: >>> import re >>> def titlecase(s): From b4abef229536c80138ec139f01671d38c0b5a4e5 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 7 Apr 2022 07:27:40 -0700 Subject: [PATCH 048/237] c-api docs: There are five fields, not four (GH-32379) (cherry picked from commit 4c92427fb85e420404a9bd26347e32acc1bbd3b7) Co-authored-by: Jelle Zijlstra --- Doc/c-api/memory.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index ced7ca79ca5900..f17d24bda589c1 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -403,7 +403,7 @@ Customize Memory Allocators .. c:type:: PyMemAllocatorEx Structure used to describe a memory block allocator. The structure has - four fields: + the following fields: +----------------------------------------------------------+---------------------------------------+ | Field | Meaning | From 877fd622e81989e6e9cb5401ac4974c9fd5a128a Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 7 Apr 2022 09:51:40 -0700 Subject: [PATCH 049/237] ssl docs: Fix typo (GH-32336) (cherry picked from commit 9ee2d3a93914776d15ac5cc7c44bb3aaca3e0fe5) Co-authored-by: Frederick --- Doc/library/ssl.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 84abbaf935374c..d21d6122e0a801 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -1548,7 +1548,7 @@ to speed up repeated connections from the same clients. string must be the path to a single file in PEM format containing the certificate as well as any number of CA certificates needed to establish the certificate's authenticity. The *keyfile* string, if present, must - point to a file containing the private key in. Otherwise the private + point to a file containing the private key. Otherwise the private key will be taken from *certfile* as well. See the discussion of :ref:`ssl-certificates` for more information on how the certificate is stored in the *certfile*. From b0ec17b6d9e0fb61081b6d15a1b2a14b607851b7 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Thu, 7 Apr 2022 23:21:03 +0100 Subject: [PATCH 050/237] bpo-47103: Copy pgort140.dll into output directory when building PGInstrument on Windows (GH-32083) --- Lib/test/test_embed.py | 19 +++++-------------- .../2022-03-23-20-01-16.bpo-47103.b4-00F.rst | 2 ++ PCbuild/python.vcxproj | 15 +++++++++++---- 3 files changed, 18 insertions(+), 18 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2022-03-23-20-01-16.bpo-47103.b4-00F.rst diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 503d4925c9402f..8c343f37210850 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -1195,20 +1195,11 @@ def tmpdir_with_python(self): if MS_WINDOWS: # Copy pythonXY.dll (or pythonXY_d.dll) - ver = sys.version_info - dll = f'python{ver.major}{ver.minor}' - dll3 = f'python{ver.major}' - if debug_build(sys.executable): - dll += '_d' - dll3 += '_d' - dll += '.dll' - dll3 += '.dll' - dll = os.path.join(os.path.dirname(self.test_exe), dll) - dll3 = os.path.join(os.path.dirname(self.test_exe), dll3) - dll_copy = os.path.join(tmpdir, os.path.basename(dll)) - dll3_copy = os.path.join(tmpdir, os.path.basename(dll3)) - shutil.copyfile(dll, dll_copy) - shutil.copyfile(dll3, dll3_copy) + import fnmatch + exedir = os.path.dirname(self.test_exe) + for f in os.listdir(exedir): + if fnmatch.fnmatch(f, '*.dll'): + shutil.copyfile(os.path.join(exedir, f), os.path.join(tmpdir, f)) # Copy Python program exec_copy = os.path.join(tmpdir, os.path.basename(self.test_exe)) diff --git a/Misc/NEWS.d/next/Build/2022-03-23-20-01-16.bpo-47103.b4-00F.rst b/Misc/NEWS.d/next/Build/2022-03-23-20-01-16.bpo-47103.b4-00F.rst new file mode 100644 index 00000000000000..c1e01adce0d269 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-03-23-20-01-16.bpo-47103.b4-00F.rst @@ -0,0 +1,2 @@ +Windows ``PGInstrument`` builds now copy a required DLL into the output +directory, making it easier to run the profile stage of a PGO build. diff --git a/PCbuild/python.vcxproj b/PCbuild/python.vcxproj index b58945a4d19b6c..b6dcf14823546e 100644 --- a/PCbuild/python.vcxproj +++ b/PCbuild/python.vcxproj @@ -128,9 +128,6 @@ set PYTHONPATH=$(PySourcePath)Lib - <_PGOPath Condition="$(Configuration) == 'PGInstrument' and $(Platform) == 'Win32'">@set PATH=%PATH%%3B$(VCInstallDir)bin - <_PGOPath Condition="$(Configuration) == 'PGInstrument' and $(Platform) == 'x64'">@set PATH=%PATH%%3B$(VCInstallDir)bin\amd64 - <_PGOPath Condition="$(Configuration) == 'PGInstrument' and $(VC_PGO_RunTime_Dir) != ''">@set PATH=%PATH%%3B$(VC_PGO_RunTime_Dir) <_Content>@rem This script invokes the most recently built Python with all arguments @rem passed through to the interpreter. This file is generated by the @rem build process and any changes *will* be thrown away by the next @@ -140,11 +137,21 @@ set PYTHONPATH=$(PySourcePath)Lib @echo Running $(Configuration)^|$(Platform) interpreter... @setlocal @set PYTHONHOME=$(PySourcePath) -$(_PGOPath) @"$(OutDir)python$(PyDebugExt).exe" %* <_ExistingContent Condition="Exists('$(PySourcePath)python.bat')">$([System.IO.File]::ReadAllText('$(PySourcePath)python.bat')) + + + <_PGORT Include="$(VCToolsInstallDir)bin\Hostx86\x86\pgort140.dll" Condition="$(Platform) == 'Win32'" /> + <_PGORT Include="$(VCToolsInstallDir)bin\Hostx64\x64\pgort140.dll" Condition="$(Platform) == 'x64'" /> + <_PGORT Include="$(VCToolsInstallDir)bin\arm64\pgort140.dll" Condition="$(Platform) == 'ARM64'" /> + + + + + + From 89192c46da7b984811ff3bd648f8e827e4ef053c Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 7 Apr 2022 18:56:17 -0700 Subject: [PATCH 051/237] pickle docs: Fix typos and improve wording (GH-24776) (GH-32395) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jelle Zijlstra (cherry picked from commit 1d0f08fa46b54f5a9b43a916b66d50b97d56cf36) Co-authored-by: Géry Ogam --- Doc/library/pickle.rst | 47 +++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst index be48561ed10ac8..f7db0e8415f4c7 100644 --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -147,7 +147,7 @@ to read the pickle produced. earlier versions of Python. * Protocol version 2 was introduced in Python 2.3. It provides much more - efficient pickling of :term:`new-style class`\es. Refer to :pep:`307` for + efficient pickling of :term:`new-style classes `. Refer to :pep:`307` for information about improvements brought by protocol 2. * Protocol version 3 was added in Python 3.0. It has explicit support for @@ -261,7 +261,7 @@ process more convenient: protocol argument is needed. Bytes past the pickled representation of the object are ignored. - Arguments *file*, *fix_imports*, *encoding*, *errors*, *strict* and *buffers* + Arguments *fix_imports*, *encoding*, *errors*, *strict* and *buffers* have the same meaning as in the :class:`Unpickler` constructor. .. versionchanged:: 3.8 @@ -368,7 +368,7 @@ The :mod:`pickle` module exports three classes, :class:`Pickler`, .. versionadded:: 3.3 - .. method:: reducer_override(self, obj) + .. method:: reducer_override(obj) Special reducer that can be defined in :class:`Pickler` subclasses. This method has priority over any reducer in the :attr:`dispatch_table`. It @@ -494,20 +494,18 @@ What can be pickled and unpickled? The following types can be pickled: -* ``None``, ``True``, and ``False`` - -* integers, floating point numbers, complex numbers +* ``None``, ``True``, and ``False``; -* strings, bytes, bytearrays +* integers, floating-point numbers, complex numbers; -* tuples, lists, sets, and dictionaries containing only picklable objects +* strings, bytes, bytearrays; -* functions defined at the top level of a module (using :keyword:`def`, not - :keyword:`lambda`) +* tuples, lists, sets, and dictionaries containing only picklable objects; -* built-in functions defined at the top level of a module +* functions (built-in and user-defined) defined at the top level of a module + (using :keyword:`def`, not :keyword:`lambda`); -* classes that are defined at the top level of a module +* classes defined at the top level of a module; * instances of such classes whose :attr:`~object.__dict__` or the result of calling :meth:`__getstate__` is picklable (see section :ref:`pickle-inst` for @@ -520,14 +518,14 @@ structure may exceed the maximum recursion depth, a :exc:`RecursionError` will b raised in this case. You can carefully raise this limit with :func:`sys.setrecursionlimit`. -Note that functions (built-in and user-defined) are pickled by "fully qualified" -name reference, not by value. [#]_ This means that only the function name is +Note that functions (built-in and user-defined) are pickled by fully qualified +name, not by value. [#]_ This means that only the function name is pickled, along with the name of the module the function is defined in. Neither the function's code, nor any of its function attributes are pickled. Thus the defining module must be importable in the unpickling environment, and the module must contain the named object, otherwise an exception will be raised. [#]_ -Similarly, classes are pickled by named reference, so the same restrictions in +Similarly, classes are pickled by fully qualified name, so the same restrictions in the unpickling environment apply. Note that none of the class's code or data is pickled, so in the following example the class attribute ``attr`` is not restored in the unpickling environment:: @@ -537,7 +535,7 @@ restored in the unpickling environment:: picklestring = pickle.dumps(Foo) -These restrictions are why picklable functions and classes must be defined in +These restrictions are why picklable functions and classes must be defined at the top level of a module. Similarly, when class instances are pickled, their class's code and data are not @@ -569,7 +567,7 @@ implementation of this behaviour:: def save(obj): return (obj.__class__, obj.__dict__) - def load(cls, attributes): + def restore(cls, attributes): obj = cls.__new__(cls) obj.__dict__.update(attributes) return obj @@ -788,14 +786,15 @@ the code :: f = io.BytesIO() p = MyPickler(f) -does the same, but all instances of ``MyPickler`` will by default -share the same dispatch table. The equivalent code using the -:mod:`copyreg` module is :: +does the same but all instances of ``MyPickler`` will by default +share the private dispatch table. On the other hand, the code :: copyreg.pickle(SomeClass, reduce_SomeClass) f = io.BytesIO() p = pickle.Pickler(f) +modifies the global dispatch table shared by all users of the :mod:`copyreg` module. + .. _pickle-state: Handling Stateful Objects @@ -1098,7 +1097,7 @@ Here is an example of an unpickler allowing only few safe classes from the """Helper function analogous to pickle.loads().""" return RestrictedUnpickler(io.BytesIO(s)).load() -A sample usage of our unpickler working has intended:: +A sample usage of our unpickler working as intended:: >>> restricted_loads(pickle.dumps([1, 2, range(15)])) [1, 2, range(0, 15)] @@ -1142,7 +1141,7 @@ For the simplest code, use the :func:`dump` and :func:`load` functions. :: # An arbitrary collection of objects supported by pickle. data = { - 'a': [1, 2.0, 3, 4+6j], + 'a': [1, 2.0, 3+4j], 'b': ("character string", b"byte string"), 'c': {None, True, False} } @@ -1198,6 +1197,6 @@ The following example reads the resulting pickled data. :: operations. .. [#] The limitation on alphanumeric characters is due to the fact - the persistent IDs, in protocol 0, are delimited by the newline + that persistent IDs in protocol 0 are delimited by the newline character. Therefore if any kind of newline characters occurs in - persistent IDs, the resulting pickle will become unreadable. + persistent IDs, the resulting pickled data will become unreadable. From 69edc30d2b47fe9b95975b1b66214e7473a9ccf5 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 8 Apr 2022 10:06:19 -0700 Subject: [PATCH 052/237] Fix bad grammar and import docstring for split/rsplit (GH-32381) (GH-32416) --- Objects/clinic/unicodeobject.c.h | 34 ++++++++++++++++++++------------ Objects/unicodeobject.c | 25 ++++++++++++++--------- 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/Objects/clinic/unicodeobject.c.h b/Objects/clinic/unicodeobject.c.h index 9ef8ce2e35364c..803b5f2353f9e7 100644 --- a/Objects/clinic/unicodeobject.c.h +++ b/Objects/clinic/unicodeobject.c.h @@ -858,15 +858,21 @@ PyDoc_STRVAR(unicode_split__doc__, "split($self, /, sep=None, maxsplit=-1)\n" "--\n" "\n" -"Return a list of the words in the string, using sep as the delimiter string.\n" +"Return a list of the substrings in the string, using sep as the separator string.\n" "\n" " sep\n" -" The delimiter according which to split the string.\n" -" None (the default value) means split according to any whitespace,\n" -" and discard empty strings from the result.\n" +" The separator used to split the string.\n" +"\n" +" When set to None (the default value), will split on any whitespace\n" +" character (including \\\\n \\\\r \\\\t \\\\f and spaces) and will discard\n" +" empty strings from the result.\n" " maxsplit\n" -" Maximum number of splits to do.\n" -" -1 (the default value) means no limit."); +" Maximum number of splits (starting from the left).\n" +" -1 (the default value) means no limit.\n" +"\n" +"Note, str.split() is mainly useful for data that has been intentionally\n" +"delimited. With natural text that includes punctuation, consider using\n" +"the regular expression module."); #define UNICODE_SPLIT_METHODDEF \ {"split", (PyCFunction)(void(*)(void))unicode_split, METH_FASTCALL|METH_KEYWORDS, unicode_split__doc__}, @@ -953,17 +959,19 @@ PyDoc_STRVAR(unicode_rsplit__doc__, "rsplit($self, /, sep=None, maxsplit=-1)\n" "--\n" "\n" -"Return a list of the words in the string, using sep as the delimiter string.\n" +"Return a list of the substrings in the string, using sep as the separator string.\n" "\n" " sep\n" -" The delimiter according which to split the string.\n" -" None (the default value) means split according to any whitespace,\n" -" and discard empty strings from the result.\n" +" The separator used to split the string.\n" +"\n" +" When set to None (the default value), will split on any whitespace\n" +" character (including \\\\n \\\\r \\\\t \\\\f and spaces) and will discard\n" +" empty strings from the result.\n" " maxsplit\n" -" Maximum number of splits to do.\n" +" Maximum number of splits (starting from the left).\n" " -1 (the default value) means no limit.\n" "\n" -"Splits are done starting at the end of the string and working to the front."); +"Splitting starts at the end of the string and works to the front."); #define UNICODE_RSPLIT_METHODDEF \ {"rsplit", (PyCFunction)(void(*)(void))unicode_rsplit, METH_FASTCALL|METH_KEYWORDS, unicode_rsplit__doc__}, @@ -1327,4 +1335,4 @@ unicode_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=f10cf85d3935b3b7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c494bed46209961d input=a9049054013a1b77]*/ diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 377fa6c8e2a28b..38a7b3c8b44b9b 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -13478,19 +13478,26 @@ PyUnicode_Split(PyObject *s, PyObject *sep, Py_ssize_t maxsplit) str.split as unicode_split sep: object = None - The delimiter according which to split the string. - None (the default value) means split according to any whitespace, - and discard empty strings from the result. + The separator used to split the string. + + When set to None (the default value), will split on any whitespace + character (including \\n \\r \\t \\f and spaces) and will discard + empty strings from the result. maxsplit: Py_ssize_t = -1 - Maximum number of splits to do. + Maximum number of splits (starting from the left). -1 (the default value) means no limit. -Return a list of the words in the string, using sep as the delimiter string. +Return a list of the substrings in the string, using sep as the separator string. + +Note, str.split() is mainly useful for data that has been intentionally +delimited. With natural text that includes punctuation, consider using +the regular expression module. + [clinic start generated code]*/ static PyObject * unicode_split_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit) -/*[clinic end generated code: output=3a65b1db356948dc input=606e750488a82359]*/ +/*[clinic end generated code: output=3a65b1db356948dc input=906d953b44efc43b]*/ { if (sep == Py_None) return split(self, NULL, maxsplit); @@ -13661,14 +13668,14 @@ PyUnicode_RSplit(PyObject *s, PyObject *sep, Py_ssize_t maxsplit) /*[clinic input] str.rsplit as unicode_rsplit = str.split -Return a list of the words in the string, using sep as the delimiter string. +Return a list of the substrings in the string, using sep as the separator string. -Splits are done starting at the end of the string and working to the front. +Splitting starts at the end of the string and works to the front. [clinic start generated code]*/ static PyObject * unicode_rsplit_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit) -/*[clinic end generated code: output=c2b815c63bcabffc input=12ad4bf57dd35f15]*/ +/*[clinic end generated code: output=c2b815c63bcabffc input=ea78406060fce33c]*/ { if (sep == Py_None) return rsplit(self, NULL, maxsplit); From 89697f7374ea947ebe8e36131e2d3e21fff6fa1d Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 8 Apr 2022 11:10:38 -0700 Subject: [PATCH 053/237] bpo-47260: Fix os.closerange() potentially being a no-op in a seccomp sandbox (GH-32418) _Py_closerange() currently assumes that close_range() closes all file descriptors even if it returns an error (other than ENOSYS). This assumption can be wrong on Linux if a seccomp sandbox denies the underlying syscall, pretending that it returns EPERM or EACCES. In this case _Py_closerange() won't close any descriptors at all, which in the worst case can be a security issue. Fix this by falling back to other methods in case of any close_range() error. Note that fallbacks will not be triggered on any problems with closing individual file descriptors because close_range() is documented to ignore such errors on both Linux[1] and FreeBSD[2]. [1] https://man7.org/linux/man-pages/man2/close_range.2.html [2] https://www.freebsd.org/cgi/man.cgi?query=close_range&sektion=2 (cherry picked from commit 1c8b3b5d66a629258f1db16939b996264a8b9c37) Co-authored-by: Alexey Izbyshev --- .../Library/2022-04-08-14-30-53.bpo-47260.TtcNxI.rst | 2 ++ Python/fileutils.c | 9 +++++---- 2 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-04-08-14-30-53.bpo-47260.TtcNxI.rst diff --git a/Misc/NEWS.d/next/Library/2022-04-08-14-30-53.bpo-47260.TtcNxI.rst b/Misc/NEWS.d/next/Library/2022-04-08-14-30-53.bpo-47260.TtcNxI.rst new file mode 100644 index 00000000000000..300baa19c279a3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-08-14-30-53.bpo-47260.TtcNxI.rst @@ -0,0 +1,2 @@ +Fix ``os.closerange()`` potentially being a no-op in a Linux seccomp +sandbox. diff --git a/Python/fileutils.c b/Python/fileutils.c index c3144ee40782e8..3b53baa00eeb10 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -2395,10 +2395,11 @@ _Py_closerange(int first, int last) first = Py_MAX(first, 0); _Py_BEGIN_SUPPRESS_IPH #ifdef HAVE_CLOSE_RANGE - if (close_range(first, last, 0) == 0 || errno != ENOSYS) { - /* Any errors encountered while closing file descriptors are ignored; - * ENOSYS means no kernel support, though, - * so we'll fallback to the other methods. */ + if (close_range(first, last, 0) == 0) { + /* close_range() ignores errors when it closes file descriptors. + * Possible reasons of an error return are lack of kernel support + * or denial of the underlying syscall by a seccomp sandbox on Linux. + * Fallback to other methods in case of any error. */ } else #endif /* HAVE_CLOSE_RANGE */ From 72114c06fd8f105437d671277b0593a378ecc3f4 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 13 Apr 2022 18:38:37 -0700 Subject: [PATCH 054/237] gh-91421: Use constant value check during runtime (GH-91422) (GH-91492) The left-hand side expression of the if-check can be converted to a constant by the compiler, but the addition on the right-hand side is performed during runtime. Move the addition from the right-hand side to the left-hand side by turning it into a subtraction there. Since the values are known to be large enough to not turn negative, this is a safe operation. Prevents a very unlikely integer overflow on 32 bit systems. Fixes GH-91421. (cherry picked from commit 0859368335d470b9ff33fc53ed9a85ec2654b278) Co-authored-by: Tobias Stoeckmann --- .../2022-04-10-22-57-27.gh-issue-91421.dHhv6U.rst | 1 + Objects/unicodeobject.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-04-10-22-57-27.gh-issue-91421.dHhv6U.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-04-10-22-57-27.gh-issue-91421.dHhv6U.rst b/Misc/NEWS.d/next/Core and Builtins/2022-04-10-22-57-27.gh-issue-91421.dHhv6U.rst new file mode 100644 index 00000000000000..898eb0df18d01e --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-04-10-22-57-27.gh-issue-91421.dHhv6U.rst @@ -0,0 +1 @@ +Fix a potential integer overflow in _Py_DecodeUTF8Ex. diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 38a7b3c8b44b9b..5ddde5054428a2 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -5373,7 +5373,7 @@ _Py_DecodeUTF8Ex(const char *s, Py_ssize_t size, wchar_t **wstr, size_t *wlen, /* Note: size will always be longer than the resulting Unicode character count */ - if (PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(wchar_t) < (size + 1)) { + if (PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(wchar_t) - 1 < size) { return -1; } From 52ce75fc1ee31032ce64bee4f01f1c1e70b39c28 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 14 Apr 2022 02:18:31 -0700 Subject: [PATCH 055/237] gh-90879: Fix missing parameter for put_nowait() (GH-91514) (cherry picked from commit 0fc3517cf46ec79b4681c31916d4081055a7ed09) Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> --- Doc/library/queue.rst | 4 ++-- Lib/queue.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/queue.rst b/Doc/library/queue.rst index cbf27d2bb10d04..540dde9e154e80 100644 --- a/Doc/library/queue.rst +++ b/Doc/library/queue.rst @@ -138,7 +138,7 @@ provide the public methods described below. .. method:: Queue.put_nowait(item) - Equivalent to ``put(item, False)``. + Equivalent to ``put(item, block=False)``. .. method:: Queue.get(block=True, timeout=None) @@ -248,7 +248,7 @@ SimpleQueue Objects .. method:: SimpleQueue.put_nowait(item) - Equivalent to ``put(item)``, provided for compatibility with + Equivalent to ``put(item, block=False)``, provided for compatibility with :meth:`Queue.put_nowait`. diff --git a/Lib/queue.py b/Lib/queue.py index 10dbcbc18ece85..55f50088460f9e 100644 --- a/Lib/queue.py +++ b/Lib/queue.py @@ -298,7 +298,7 @@ def get(self, block=True, timeout=None): def put_nowait(self, item): '''Put an item into the queue without blocking. - This is exactly equivalent to `put(item)` and is only provided + This is exactly equivalent to `put(item, block=False)` and is only provided for compatibility with the Queue class. ''' return self.put(item, block=False) From 35fef2711033ce793ec1cb43dfbd95e2d06ab7bb Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 14 Apr 2022 08:02:03 -0700 Subject: [PATCH 056/237] Add redirects to Misc/NEWS bpo links (GH-91454) (GH-91535) (cherry picked from commit 17dbb6bc10ca8a8b602335414c047294f00afcbe) Co-authored-by: Ezio Melotti --- Doc/tools/extensions/pyspecific.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index 92fc5e7c71cd7d..7f505a1ede89a4 100644 --- a/Doc/tools/extensions/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -433,7 +433,8 @@ def run(self): text = 'The NEWS file is not available.' node = nodes.strong(text, text) return [node] - content = issue_re.sub(r'`bpo-\1 `__', + content = issue_re.sub(r'`bpo-\1 `__', content) content = whatsnew_re.sub(r'\1', content) # remove first 3 lines as they are the main heading From de7b7565219a24422bf34792239192a57c925281 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 14 Apr 2022 18:23:20 -0700 Subject: [PATCH 057/237] gh-70979: Fix runpy.run_path parameter name in docs (GH-32265) Noticed while reviewing GH-30729. (cherry picked from commit f1e989b04507db6f0adbccb5e1624d81cb217ea8) Co-authored-by: Jelle Zijlstra --- Doc/library/runpy.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/runpy.rst b/Doc/library/runpy.rst index af35e81a2d4523..26a4f1435214e8 100644 --- a/Doc/library/runpy.rst +++ b/Doc/library/runpy.rst @@ -93,7 +93,7 @@ The :mod:`runpy` module provides two functions: run this way, as well as ensuring the real module name is always accessible as ``__spec__.name``. -.. function:: run_path(file_path, init_globals=None, run_name=None) +.. function:: run_path(path_name, init_globals=None, run_name=None) .. index:: module: __main__ @@ -140,7 +140,7 @@ The :mod:`runpy` module provides two functions: A number of alterations are also made to the :mod:`sys` module. Firstly, ``sys.path`` may be altered as described above. ``sys.argv[0]`` is updated - with the value of ``file_path`` and ``sys.modules[__name__]`` is updated + with the value of ``path_name`` and ``sys.modules[__name__]`` is updated with a temporary module object for the module being executed. All modifications to items in :mod:`sys` are reverted before the function returns. From 289f27d06b0d19739b114f6b2f60a6264655b8f6 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 15 Apr 2022 06:55:13 -0700 Subject: [PATCH 058/237] gh-88513: clarify shutil.copytree's dirs_exist_ok arg (GH-91434) (GH-91464) * add a paragraph to document this kwarg in detail * update docstring in the source accordingly (cherry picked from commit f33e2c87a83917b5139d97fd8ef7cba7223ebef5) Co-authored-by: Jelle Zijlstra --- Doc/library/shutil.rst | 17 +++++++++++------ Lib/shutil.py | 8 +++++--- .../2022-04-10-20-28-20.bpo-44347.Q1m3DM.rst | 1 + 3 files changed, 17 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2022-04-10-20-28-20.bpo-44347.Q1m3DM.rst diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 5f71049f918e0e..8ce0e80ec81206 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -230,9 +230,8 @@ Directory and files operations dirs_exist_ok=False) Recursively copy an entire directory tree rooted at *src* to a directory - named *dst* and return the destination directory. *dirs_exist_ok* dictates - whether to raise an exception in case *dst* or any missing parent directory - already exists. + named *dst* and return the destination directory. All intermediate + directories needed to contain *dst* will also be created by default. Permissions and times of directories are copied with :func:`copystat`, individual files are copied using :func:`~shutil.copy2`. @@ -263,8 +262,14 @@ Directory and files operations If *copy_function* is given, it must be a callable that will be used to copy each file. It will be called with the source path and the destination path -   as arguments. By default, :func:`~shutil.copy2` is used, but any function -   that supports the same signature (like :func:`~shutil.copy`) can be used. + as arguments. By default, :func:`~shutil.copy2` is used, but any function + that supports the same signature (like :func:`~shutil.copy`) can be used. + + If *dirs_exist_ok* is false (the default) and *dst* already exists, a + :exc:`FileExistsError` is raised. If *dirs_exist_ok* is true, the copying + operation will continue if it encounters existing directories, and files + within the *dst* tree will be overwritten by corresponding files from the + *src* tree. .. audit-event:: shutil.copytree src,dst shutil.copytree @@ -275,7 +280,7 @@ Directory and files operations .. versionchanged:: 3.2 Added the *copy_function* argument to be able to provide a custom copy function. - Added the *ignore_dangling_symlinks* argument to silent dangling symlinks + Added the *ignore_dangling_symlinks* argument to silence dangling symlinks errors when *symlinks* is false. .. versionchanged:: 3.8 diff --git a/Lib/shutil.py b/Lib/shutil.py index 37bf98df796723..2768bcf6ab8156 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -516,9 +516,6 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False, dirs_exist_ok=False): """Recursively copy a directory tree and return the destination directory. - dirs_exist_ok dictates whether to raise an exception in case dst or any - missing parent directory already exists. - If exception(s) occur, an Error is raised with a list of reasons. If the optional symlinks flag is true, symbolic links in the @@ -549,6 +546,11 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, destination path as arguments. By default, copy2() is used, but any function that supports the same signature (like copy()) can be used. + If dirs_exist_ok is false (the default) and `dst` already exists, a + `FileExistsError` is raised. If `dirs_exist_ok` is true, the copying + operation will continue if it encounters existing directories, and files + within the `dst` tree will be overwritten by corresponding files from the + `src` tree. """ sys.audit("shutil.copytree", src, dst) with os.scandir(src) as itr: diff --git a/Misc/NEWS.d/next/Documentation/2022-04-10-20-28-20.bpo-44347.Q1m3DM.rst b/Misc/NEWS.d/next/Documentation/2022-04-10-20-28-20.bpo-44347.Q1m3DM.rst new file mode 100644 index 00000000000000..27aa5742cd0087 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-04-10-20-28-20.bpo-44347.Q1m3DM.rst @@ -0,0 +1 @@ +Clarify the meaning of *dirs_exist_ok*, a kwarg of :func:`shutil.copytree`. From 2e1f9693333534e7de73bb8790b12572f83f7129 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 15 Apr 2022 19:16:05 -0700 Subject: [PATCH 059/237] Add link to documentation translation list (GH-91560) (#91589) (cherry picked from commit c4e8a93eb3fa5e5d930cea64f213443242c2588c) Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> --- Doc/bugs.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Doc/bugs.rst b/Doc/bugs.rst index b3d057797c2561..0feddeb5793fcd 100644 --- a/Doc/bugs.rst +++ b/Doc/bugs.rst @@ -35,6 +35,10 @@ though it may take a while to be processed. `Helping with Documentation `_ Comprehensive guide for individuals that are interested in contributing to Python documentation. + `Documentation Translations `_ + A list of GitHub pages for documentation translation and their primary contacts. + + .. _using-the-tracker: Using the Python issue tracker From f5542ecf6d340eaaf86f31d90a7a7ff7a99f25a2 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 15 Apr 2022 21:38:11 -0700 Subject: [PATCH 060/237] gh-82849: revise intro to os.path.rst (GH-32232) * revise the first paragraph of docs for os.path * add a mention of `os.PathLike` protocol * remove warnings rendered irrelevant by :pep:`383` and :pep:`529` Co-authored-by: Jelle Zijlstra (cherry picked from commit 468314cc8bfdb6fd328cbbbb7d0807728f25e043) Co-authored-by: Jack DeVries --- Doc/library/os.path.rst | 15 ++++----------- .../2022-04-01-09-28-31.bpo-38668.j4mrqW.rst | 3 +++ 2 files changed, 7 insertions(+), 11 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2022-04-01-09-28-31.bpo-38668.j4mrqW.rst diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst index 6b15a113f54506..c201b1460ede30 100644 --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -11,16 +11,10 @@ -------------- -This module implements some useful functions on pathnames. To read or -write files see :func:`open`, and for accessing the filesystem see the -:mod:`os` module. The path parameters can be passed as either strings, -or bytes. Applications are encouraged to represent file names as -(Unicode) character strings. Unfortunately, some file names may not be -representable as strings on Unix, so applications that need to support -arbitrary file names on Unix should use bytes objects to represent -path names. Vice versa, using bytes objects cannot represent all file -names on Windows (in the standard ``mbcs`` encoding), hence Windows -applications should use string objects to access all files. +This module implements some useful functions on pathnames. To read or write +files see :func:`open`, and for accessing the filesystem see the :mod:`os` +module. The path parameters can be passed as strings, or bytes, or any object +implementing the :class:`os.PathLike` protocol. Unlike a unix shell, Python does not do any *automatic* path expansions. Functions such as :func:`expanduser` and :func:`expandvars` can be invoked @@ -38,7 +32,6 @@ the :mod:`glob` module.) their parameters. The result is an object of the same type, if a path or file name is returned. - .. note:: Since different operating systems have different path name conventions, there diff --git a/Misc/NEWS.d/next/Documentation/2022-04-01-09-28-31.bpo-38668.j4mrqW.rst b/Misc/NEWS.d/next/Documentation/2022-04-01-09-28-31.bpo-38668.j4mrqW.rst new file mode 100644 index 00000000000000..512f0deb3543c7 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-04-01-09-28-31.bpo-38668.j4mrqW.rst @@ -0,0 +1,3 @@ +Update the introduction to documentation for :mod:`os.path` to remove +warnings that became irrelevant after the implementations of :pep:`383` and +:pep:`529`. From 84c279b514141f608cf480905c87d48998e296d1 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 16 Apr 2022 07:59:32 -0700 Subject: [PATCH 061/237] gh-91595: fix the comparison of character and integer by using ord() (GH-91596) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix the comparison of character and integer by using ord() * 📜🤖 Added by blurb_it. Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> (cherry picked from commit 9300b6d72948b94c0924a75ea14c6298156522d0) Co-authored-by: Yu Liu --- .../next/Library/2022-04-16-05-12-13.gh-issue-91595.CocJBv.rst | 1 + Tools/gdb/libpython.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2022-04-16-05-12-13.gh-issue-91595.CocJBv.rst diff --git a/Misc/NEWS.d/next/Library/2022-04-16-05-12-13.gh-issue-91595.CocJBv.rst b/Misc/NEWS.d/next/Library/2022-04-16-05-12-13.gh-issue-91595.CocJBv.rst new file mode 100644 index 00000000000000..637079a6487a49 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-16-05-12-13.gh-issue-91595.CocJBv.rst @@ -0,0 +1 @@ +Fix the comparison of character and integer inside :func:`Tools.gdb.libpython.write_repr`. Patch by Yu Liu. diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index 270aeb426eb5b3..12b519330d8a62 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -1291,7 +1291,7 @@ def write_repr(self, out, visited): out.write('\\r') # Map non-printable US ASCII to '\xhh' */ - elif ch < ' ' or ch == 0x7F: + elif ch < ' ' or ord(ch) == 0x7F: out.write('\\x') out.write(hexdigits[(ord(ch) >> 4) & 0x000F]) out.write(hexdigits[ord(ch) & 0x000F]) From 9a458934f7be37c59525350f1f9ecbdcd69903c1 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Sat, 16 Apr 2022 13:48:11 -0700 Subject: [PATCH 062/237] [3.10] gh-91607: Fix several test_concurrent_futures tests to actually test what they claim (GH-91600) (#91612) * Fix test_concurrent_futures to actually test what it says. Many ProcessPoolExecutor based tests were ignoring the mp_context and using the default instead. This meant we lacked proper test coverage of all of them. Also removes the old _prime_executor() worker delay seeding code as it appears to have no point and causes 20-30 seconds extra latency on this already long test. It also interfered with some of the refactoring to fix the above to not needlessly create their own executor when setUp has already created an appropriate one. * Don't import the name from multiprocessing directly to avoid confusion. (cherry picked from commit 7fa3a5a2197896066e3fe53ee325ac6ab54c3414) Co-authored-by: Gregory P. Smith --- Lib/test/test_concurrent_futures.py | 96 ++++++++----------- ...2-04-16-17-54-05.gh-issue-91607.FnXjtW.rst | 1 + 2 files changed, 43 insertions(+), 54 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2022-04-16-17-54-05.gh-issue-91607.FnXjtW.rst diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index 50fa1f189b174f..d3d912892cc2d5 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -26,10 +26,10 @@ PENDING, RUNNING, CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED, Future, BrokenExecutor) from concurrent.futures.process import BrokenProcessPool, _check_system_limits -from multiprocessing import get_context import multiprocessing.process import multiprocessing.util +import multiprocessing as mp if support.check_sanitizer(address=True, memory=True): @@ -131,7 +131,6 @@ def setUp(self): self.executor = self.executor_type( max_workers=self.worker_count, **self.executor_kwargs) - self._prime_executor() def tearDown(self): self.executor.shutdown(wait=True) @@ -145,15 +144,7 @@ def tearDown(self): super().tearDown() def get_context(self): - return get_context(self.ctx) - - def _prime_executor(self): - # Make sure that the executor is ready to do work before running the - # tests. This should reduce the probability of timeouts in the tests. - futures = [self.executor.submit(time.sleep, 0.1) - for _ in range(self.worker_count)] - for f in futures: - f.result() + return mp.get_context(self.ctx) class ThreadPoolMixin(ExecutorMixin): @@ -276,9 +267,6 @@ def test_initializer(self): with self.assertRaises(BrokenExecutor): self.executor.submit(get_init_status) - def _prime_executor(self): - pass - @contextlib.contextmanager def _assert_logged(self, msg): if self.log_queue is not None: @@ -365,14 +353,14 @@ def test_hang_issue12364(self): f.result() def test_cancel_futures(self): - executor = self.executor_type(max_workers=3) - fs = [executor.submit(time.sleep, .1) for _ in range(50)] - executor.shutdown(cancel_futures=True) + assert self.worker_count <= 5, "test needs few workers" + fs = [self.executor.submit(time.sleep, .1) for _ in range(50)] + self.executor.shutdown(cancel_futures=True) # We can't guarantee the exact number of cancellations, but we can - # guarantee that *some* were cancelled. With setting max_workers to 3, - # most of the submitted futures should have been cancelled. + # guarantee that *some* were cancelled. With few workers, many of + # the submitted futures should have been cancelled. cancelled = [fut for fut in fs if fut.cancelled()] - self.assertTrue(len(cancelled) >= 35, msg=f"{len(cancelled)=}") + self.assertGreater(len(cancelled), 20) # Ensure the other futures were able to finish. # Use "not fut.cancelled()" instead of "fut.done()" to include futures @@ -385,33 +373,32 @@ def test_cancel_futures(self): # Similar to the number of cancelled futures, we can't guarantee the # exact number that completed. But, we can guarantee that at least # one finished. - self.assertTrue(len(others) > 0, msg=f"{len(others)=}") + self.assertGreater(len(others), 0) - def test_hang_issue39205(self): + def test_hang_gh83386(self): """shutdown(wait=False) doesn't hang at exit with running futures. - See https://bugs.python.org/issue39205. + See https://github.com/python/cpython/issues/83386. """ if self.executor_type == futures.ProcessPoolExecutor: raise unittest.SkipTest( - "Hangs due to https://bugs.python.org/issue39205") + "Hangs, see https://github.com/python/cpython/issues/83386") rc, out, err = assert_python_ok('-c', """if True: from concurrent.futures import {executor_type} from test.test_concurrent_futures import sleep_and_print if __name__ == "__main__": + if {context!r}: multiprocessing.set_start_method({context!r}) t = {executor_type}(max_workers=3) t.submit(sleep_and_print, 1.0, "apple") t.shutdown(wait=False) - """.format(executor_type=self.executor_type.__name__)) + """.format(executor_type=self.executor_type.__name__, + context=getattr(self, 'ctx', None))) self.assertFalse(err) self.assertEqual(out.strip(), b"apple") class ThreadPoolShutdownTest(ThreadPoolMixin, ExecutorShutdownTest, BaseTestCase): - def _prime_executor(self): - pass - def test_threads_terminate(self): def acquire_lock(lock): lock.acquire() @@ -506,14 +493,11 @@ def test_cancel_futures_wait_false(self): class ProcessPoolShutdownTest(ExecutorShutdownTest): - def _prime_executor(self): - pass - def test_processes_terminate(self): def acquire_lock(lock): lock.acquire() - mp_context = get_context() + mp_context = self.get_context() sem = mp_context.Semaphore(0) for _ in range(3): self.executor.submit(acquire_lock, sem) @@ -527,7 +511,8 @@ def acquire_lock(lock): p.join() def test_context_manager_shutdown(self): - with futures.ProcessPoolExecutor(max_workers=5) as e: + with futures.ProcessPoolExecutor( + max_workers=5, mp_context=self.get_context()) as e: processes = e._processes self.assertEqual(list(e.map(abs, range(-5, 5))), [5, 4, 3, 2, 1, 0, 1, 2, 3, 4]) @@ -536,7 +521,8 @@ def test_context_manager_shutdown(self): p.join() def test_del_shutdown(self): - executor = futures.ProcessPoolExecutor(max_workers=5) + executor = futures.ProcessPoolExecutor( + max_workers=5, mp_context=self.get_context()) res = executor.map(abs, range(-5, 5)) executor_manager_thread = executor._executor_manager_thread processes = executor._processes @@ -559,7 +545,8 @@ def test_del_shutdown(self): def test_shutdown_no_wait(self): # Ensure that the executor cleans up the processes when calling # shutdown with wait=False - executor = futures.ProcessPoolExecutor(max_workers=5) + executor = futures.ProcessPoolExecutor( + max_workers=5, mp_context=self.get_context()) res = executor.map(abs, range(-5, 5)) processes = executor._processes call_queue = executor._call_queue @@ -936,7 +923,7 @@ def submit(pool): pool.submit(submit, pool) for _ in range(50): - with futures.ProcessPoolExecutor(1, mp_context=get_context('fork')) as workers: + with futures.ProcessPoolExecutor(1, mp_context=mp.get_context('fork')) as workers: workers.submit(tuple) @@ -1006,7 +993,7 @@ def test_traceback(self): def test_ressources_gced_in_workers(self): # Ensure that argument for a job are correctly gc-ed after the job # is finished - mgr = get_context(self.ctx).Manager() + mgr = self.get_context().Manager() obj = EventfulGCObj(mgr) future = self.executor.submit(id, obj) future.result() @@ -1022,36 +1009,37 @@ def test_ressources_gced_in_workers(self): mgr.join() def test_saturation(self): - executor = self.executor_type(4) - mp_context = get_context() + executor = self.executor + mp_context = self.get_context() sem = mp_context.Semaphore(0) job_count = 15 * executor._max_workers - try: - for _ in range(job_count): - executor.submit(sem.acquire) - self.assertEqual(len(executor._processes), executor._max_workers) - for _ in range(job_count): - sem.release() - finally: - executor.shutdown() + for _ in range(job_count): + executor.submit(sem.acquire) + self.assertEqual(len(executor._processes), executor._max_workers) + for _ in range(job_count): + sem.release() def test_idle_process_reuse_one(self): - executor = self.executor_type(4) + executor = self.executor + assert executor._max_workers >= 4 executor.submit(mul, 21, 2).result() executor.submit(mul, 6, 7).result() executor.submit(mul, 3, 14).result() self.assertEqual(len(executor._processes), 1) - executor.shutdown() def test_idle_process_reuse_multiple(self): - executor = self.executor_type(4) + executor = self.executor + assert executor._max_workers <= 5 executor.submit(mul, 12, 7).result() executor.submit(mul, 33, 25) executor.submit(mul, 25, 26).result() executor.submit(mul, 18, 29) - self.assertLessEqual(len(executor._processes), 2) + executor.submit(mul, 1, 2).result() + executor.submit(mul, 0, 9) + self.assertLessEqual(len(executor._processes), 3) executor.shutdown() + create_executor_tests(ProcessPoolExecutorTest, executor_mixins=(ProcessPoolForkMixin, ProcessPoolForkserverMixin, @@ -1153,7 +1141,7 @@ def _check_crash(self, error, func, *args, ignore_stderr=False): self.executor.shutdown(wait=True) executor = self.executor_type( - max_workers=2, mp_context=get_context(self.ctx)) + max_workers=2, mp_context=self.get_context()) res = executor.submit(func, *args) if ignore_stderr: @@ -1232,7 +1220,7 @@ def test_shutdown_deadlock(self): # if a worker fails after the shutdown call. self.executor.shutdown(wait=True) with self.executor_type(max_workers=2, - mp_context=get_context(self.ctx)) as executor: + mp_context=self.get_context()) as executor: self.executor = executor # Allow clean up in fail_on_deadlock f = executor.submit(_crash, delay=.1) executor.shutdown(wait=True) @@ -1245,7 +1233,7 @@ def test_shutdown_deadlock_pickle(self): # Reported in bpo-39104. self.executor.shutdown(wait=True) with self.executor_type(max_workers=2, - mp_context=get_context(self.ctx)) as executor: + mp_context=self.get_context()) as executor: self.executor = executor # Allow clean up in fail_on_deadlock # Start the executor and get the executor_manager_thread to collect diff --git a/Misc/NEWS.d/next/Tests/2022-04-16-17-54-05.gh-issue-91607.FnXjtW.rst b/Misc/NEWS.d/next/Tests/2022-04-16-17-54-05.gh-issue-91607.FnXjtW.rst new file mode 100644 index 00000000000000..32839a826a41ea --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-04-16-17-54-05.gh-issue-91607.FnXjtW.rst @@ -0,0 +1 @@ +Fix ``test_concurrent_futures`` to test the correct multiprocessing start method context in several cases where the test logic mixed this up. From 2bcfe20d9271f077b954afb4c8b45024adc10ce5 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 17 Apr 2022 14:29:21 -0700 Subject: [PATCH 063/237] gh-90923: Improve sqlite3.Connection.execute* docs (GH-91643) - Drop 'nonstandard'; it does not add any value - Try to be more concise - Make return value a little more explicit (cherry picked from commit 017f07a229a337e9c17bed8cd1879e0177a8d89d) Co-authored-by: Erlend Egeberg Aasland --- Doc/library/sqlite3.rst | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index e7c191b9f61e94..3fac2db174c338 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -378,24 +378,21 @@ Connection Objects .. method:: execute(sql[, parameters]) - This is a nonstandard shortcut that creates a cursor object by calling - the :meth:`~Connection.cursor` method, calls the cursor's - :meth:`~Cursor.execute` method with the *parameters* given, and returns - the cursor. + Create a new :class:`Cursor` object and call + :meth:`~Cursor.execute` on it with the given *sql* and *parameters*. + Return the new cursor object. .. method:: executemany(sql[, parameters]) - This is a nonstandard shortcut that creates a cursor object by - calling the :meth:`~Connection.cursor` method, calls the cursor's - :meth:`~Cursor.executemany` method with the *parameters* given, and - returns the cursor. + Create a new :class:`Cursor` object and call + :meth:`~Cursor.executemany` on it with the given *sql* and *parameters*. + Return the new cursor object. .. method:: executescript(sql_script) - This is a nonstandard shortcut that creates a cursor object by - calling the :meth:`~Connection.cursor` method, calls the cursor's - :meth:`~Cursor.executescript` method with the given *sql_script*, and - returns the cursor. + Create a new :class:`Cursor` object and call + :meth:`~Cursor.executescript` on it with the given *sql_script*. + Return the new cursor object. .. method:: create_function(name, num_params, func, *, deterministic=False) From e5636f3a0eb86932175c26fe602e0f53b6d3cbb9 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 17 Apr 2022 14:30:57 -0700 Subject: [PATCH 064/237] gh-91541: Fix error in example in modules tutorial (GH-91634) (cherry picked from commit efbc668183400597070356a2df2fbab114a53cb3) Co-authored-by: 180909 <734461790@qq.com> --- Doc/tutorial/modules.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst index f1d4957e37eb11..47c1f1877d6967 100644 --- a/Doc/tutorial/modules.rst +++ b/Doc/tutorial/modules.rst @@ -504,7 +504,7 @@ code:: __all__ = ["echo", "surround", "reverse"] This would mean that ``from sound.effects import *`` would import the three -named submodules of the :mod:`sound` package. +named submodules of the :mod:`sound.effects` package. If ``__all__`` is not defined, the statement ``from sound.effects import *`` does *not* import all submodules from the package :mod:`sound.effects` into the From 531f66ad629b02d1fc655dc1eb8956ce245dacd6 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 17 Apr 2022 14:34:41 -0700 Subject: [PATCH 065/237] gh-89885: Improve import example in language reference (GH-91523) Co-authored-by: Jelle Zijlstra (cherry picked from commit d5a69571f586080af4c29671c47f9c4bc671af7f) Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> --- Doc/reference/import.rst | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst index c01535d8049dfb..9c3c86649f555b 100644 --- a/Doc/reference/import.rst +++ b/Doc/reference/import.rst @@ -490,21 +490,19 @@ submodule. Let's say you have the following directory structure:: spam/ __init__.py foo.py - bar.py -and ``spam/__init__.py`` has the following lines in it:: +and ``spam/__init__.py`` has the following line in it:: from .foo import Foo - from .bar import Bar -then executing the following puts a name binding to ``foo`` and ``bar`` in the +then executing the following puts name bindings for ``foo`` and ``Foo`` in the ``spam`` module:: >>> import spam >>> spam.foo - >>> spam.bar - + >>> spam.Foo + Given Python's familiar name binding rules this might seem surprising, but it's actually a fundamental feature of the import system. The invariant From 0897a0bf9c75bacf428b8f6f08114fffc9f9c542 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 17 Apr 2022 21:44:58 -0700 Subject: [PATCH 066/237] Remove duplicate explanation (GH-91534) (cherry picked from commit 0e6dca01937b62c07cff5b8450b7c74c101b857d) Co-authored-by: Gouvernathor <44340603+Gouvernathor@users.noreply.github.com> --- Doc/library/stdtypes.rst | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 77b2590860e32d..365680d4503bad 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -4345,10 +4345,6 @@ then they can be used interchangeably to index the same dictionary entry. (Note however, that since computers store floating-point numbers as approximations it is usually unwise to use them as dictionary keys.) -Dictionaries can be created by placing a comma-separated list of ``key: value`` -pairs within braces, for example: ``{'jack': 4098, 'sjoerd': 4127}`` or ``{4098: -'jack', 4127: 'sjoerd'}``, or by the :class:`dict` constructor. - .. class:: dict(**kwargs) dict(mapping, **kwargs) dict(iterable, **kwargs) From 61570ae0bc1507a62bee9d8b9bc2ff7155da7061 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Tue, 19 Apr 2022 02:31:50 -0700 Subject: [PATCH 067/237] [3.10] gh-91676 gh-91260 unittest.IsolatedAsyncioTestCase no longer leaks its executor (GH-91680) For things like test_asyncio.test_thread this was causing frequent "environment modified by test" errors as the executor threads had not always stopped running after the test was over. --- Lib/unittest/async_case.py | 2 ++ .../Library/2022-04-19-04-33-39.gh-issue-91676.ceQBwh.rst | 4 ++++ 2 files changed, 6 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2022-04-19-04-33-39.gh-issue-91676.ceQBwh.rst diff --git a/Lib/unittest/async_case.py b/Lib/unittest/async_case.py index 23231199f98706..d9c694e368255d 100644 --- a/Lib/unittest/async_case.py +++ b/Lib/unittest/async_case.py @@ -148,6 +148,8 @@ def _tearDownAsyncioLoop(self): # shutdown asyncgens loop.run_until_complete(loop.shutdown_asyncgens()) finally: + # Prevent our executor environment from leaking to future tests. + loop.run_until_complete(loop.shutdown_default_executor()) asyncio.set_event_loop(None) loop.close() diff --git a/Misc/NEWS.d/next/Library/2022-04-19-04-33-39.gh-issue-91676.ceQBwh.rst b/Misc/NEWS.d/next/Library/2022-04-19-04-33-39.gh-issue-91676.ceQBwh.rst new file mode 100644 index 00000000000000..dfbaef4440e0a6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-19-04-33-39.gh-issue-91676.ceQBwh.rst @@ -0,0 +1,4 @@ +Fix :class:`unittest.IsolatedAsyncioTestCase` to shutdown the per test event +loop executor before returning from its ``run`` method so that a not yet +stopped or garbage collected executor state does not persist beyond the +test. From b865a661e3d4052e5bee17848bc6df83d121be71 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 19 Apr 2022 02:33:44 -0700 Subject: [PATCH 068/237] Doc: Fix link formatting typo (GH-91659) (cherry picked from commit 6a7a8a740e61508cb5a0fcdac8b752b6c9e5d1ea) Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> --- Doc/library/codecs.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst index 9e2eb634792823..73fbefccd728ae 100644 --- a/Doc/library/codecs.rst +++ b/Doc/library/codecs.rst @@ -1423,7 +1423,7 @@ Internationalized Domain Names (IDN)). It builds upon the ``punycode`` encoding and :mod:`stringprep`. If you need the IDNA 2008 standard from :rfc:`5891` and :rfc:`5895`, use the -third-party `idna module _`. +third-party `idna module `_. These RFCs together define a protocol to support non-ASCII characters in domain names. A domain name containing non-ASCII characters (such as From c213cccc9bffe1e6612ad19745cef8066d2e1938 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 19 Apr 2022 07:33:09 -0700 Subject: [PATCH 069/237] Add more tests for group names and refs in RE (GH-91695) (cherry picked from commit 74070085da5322ac83c954f101f2caa150655be2) Co-authored-by: Serhiy Storchaka --- Lib/test/test_re.py | 56 +++++++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 3d0637817da984..9e5223a125b052 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -218,6 +218,16 @@ def test_symbolic_groups(self): re.compile(r'(?Px)(?P=a)(?(a)y)') re.compile(r'(?Px)(?P=a1)(?(a1)y)') re.compile(r'(?Px)\1(?(1)y)') + re.compile(b'(?Px)(?P=a1)(?(a1)y)') + # New valid identifiers in Python 3 + re.compile('(?P<µ>x)(?P=µ)(?(µ)y)') + re.compile('(?P<𝔘𝔫𝔦𝔠𝔬𝔡𝔢>x)(?P=𝔘𝔫𝔦𝔠𝔬𝔡𝔢)(?(𝔘𝔫𝔦𝔠𝔬𝔡𝔢)y)') + # Support > 100 groups. + pat = '|'.join('x(?P%x)y' % (i, i) for i in range(1, 200 + 1)) + pat = '(?:%s)(?(200)z|t)' % pat + self.assertEqual(re.match(pat, 'xc8yz').span(), (0, 5)) + + def test_symbolic_groups_errors(self): self.checkPatternError(r'(?P)(?P)', "redefinition of group name 'a' as group 2; " "was group 1") @@ -243,16 +253,22 @@ def test_symbolic_groups(self): self.checkPatternError(r'(?(-1))', "bad character in group name '-1'", 3) self.checkPatternError(r'(?(1a))', "bad character in group name '1a'", 3) self.checkPatternError(r'(?(a.))', "bad character in group name 'a.'", 3) - # New valid/invalid identifiers in Python 3 - re.compile('(?P<µ>x)(?P=µ)(?(µ)y)') - re.compile('(?P<𝔘𝔫𝔦𝔠𝔬𝔡𝔢>x)(?P=𝔘𝔫𝔦𝔠𝔬𝔡𝔢)(?(𝔘𝔫𝔦𝔠𝔬𝔡𝔢)y)') self.checkPatternError('(?P<©>x)', "bad character in group name '©'", 4) + self.checkPatternError('(?P=©)', "bad character in group name '©'", 4) + self.checkPatternError('(?(©)y)', "bad character in group name '©'", 3) + + def test_symbolic_refs(self): + self.assertEqual(re.sub('(?Px)|(?Py)', r'\g', 'xx'), '') + self.assertEqual(re.sub('(?Px)|(?Py)', r'\2', 'xx'), '') + self.assertEqual(re.sub(b'(?Px)', br'\g', b'xx'), b'xx') + # New valid identifiers in Python 3 + self.assertEqual(re.sub('(?P<µ>x)', r'\g<µ>', 'xx'), 'xx') + self.assertEqual(re.sub('(?P<𝔘𝔫𝔦𝔠𝔬𝔡𝔢>x)', r'\g<𝔘𝔫𝔦𝔠𝔬𝔡𝔢>', 'xx'), 'xx') # Support > 100 groups. pat = '|'.join('x(?P%x)y' % (i, i) for i in range(1, 200 + 1)) - pat = '(?:%s)(?(200)z|t)' % pat - self.assertEqual(re.match(pat, 'xc8yz').span(), (0, 5)) + self.assertEqual(re.sub(pat, r'\g<200>', 'xc8yzxc8y'), 'c8zc8') - def test_symbolic_refs(self): + def test_symbolic_refs_errors(self): self.checkTemplateError('(?Px)', r'\g, unterminated name', 3) self.checkTemplateError('(?Px)', r'\g<', 'xx', @@ -270,18 +286,14 @@ def test_symbolic_refs(self): 'invalid group reference 2', 1) with self.assertRaisesRegex(IndexError, "unknown group name 'ab'"): re.sub('(?Px)', r'\g', 'xx') - self.assertEqual(re.sub('(?Px)|(?Py)', r'\g', 'xx'), '') - self.assertEqual(re.sub('(?Px)|(?Py)', r'\2', 'xx'), '') self.checkTemplateError('(?Px)', r'\g<-1>', 'xx', "bad character in group name '-1'", 3) - # New valid/invalid identifiers in Python 3 - self.assertEqual(re.sub('(?P<µ>x)', r'\g<µ>', 'xx'), 'xx') - self.assertEqual(re.sub('(?P<𝔘𝔫𝔦𝔠𝔬𝔡𝔢>x)', r'\g<𝔘𝔫𝔦𝔠𝔬𝔡𝔢>', 'xx'), 'xx') self.checkTemplateError('(?Px)', r'\g<©>', 'xx', "bad character in group name '©'", 3) - # Support > 100 groups. - pat = '|'.join('x(?P%x)y' % (i, i) for i in range(1, 200 + 1)) - self.assertEqual(re.sub(pat, r'\g<200>', 'xc8yzxc8y'), 'c8zc8') + self.checkTemplateError('(?Px)', r'\g<㊀>', 'xx', + "bad character in group name '㊀'", 3) + self.checkTemplateError('(?Px)', r'\g<¹>', 'xx', + "bad character in group name '¹'", 3) def test_re_subn(self): self.assertEqual(re.subn("(?i)b+", "x", "bbbb BBBB"), ('x x', 2)) @@ -543,9 +555,23 @@ def test_re_groupref_exists(self): pat = '(?:%s)(?(200)z)' % pat self.assertEqual(re.match(pat, 'xc8yz').span(), (0, 5)) - self.checkPatternError(r'(?P)(?(0))', 'bad group number', 10) + def test_re_groupref_exists_errors(self): + self.checkPatternError(r'(?P)(?(0)a|b)', 'bad group number', 10) + self.checkPatternError(r'()(?(-1)a|b)', + "bad character in group name '-1'", 5) + self.checkPatternError(r'()(?(㊀)a|b)', + "bad character in group name '㊀'", 5) + self.checkPatternError(r'()(?(¹)a|b)', + "bad character in group name '¹'", 5) + self.checkPatternError(r'()(?(1', + "missing ), unterminated name", 5) + self.checkPatternError(r'()(?(1)a', + "missing ), unterminated subpattern", 2) self.checkPatternError(r'()(?(1)a|b', 'missing ), unterminated subpattern', 2) + self.checkPatternError(r'()(?(1)a|b|c', + 'conditional backref with more than ' + 'two branches', 10) self.checkPatternError(r'()(?(1)a|b|c)', 'conditional backref with more than ' 'two branches', 10) From a885f10325eb2fc27cd50ace5614666ea688ab66 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 19 Apr 2022 17:06:00 +0200 Subject: [PATCH 070/237] gh-91231: multiprocessing BaseManager waits 1.0 second (#91701) Shutting down a multiprocessing BaseManager now waits for 1 second until the process completes, rather than 0.1 second, after the process is terminated. --- Lib/multiprocessing/managers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/multiprocessing/managers.py b/Lib/multiprocessing/managers.py index b6b4cdd9ac15eb..22292c78b7b5b3 100644 --- a/Lib/multiprocessing/managers.py +++ b/Lib/multiprocessing/managers.py @@ -677,7 +677,7 @@ def _finalize_manager(process, address, authkey, state, _Client): if hasattr(process, 'terminate'): util.info('trying to `terminate()` manager process') process.terminate() - process.join(timeout=0.1) + process.join(timeout=1.0) if process.is_alive(): util.info('manager still alive after terminate') From e7e8a9fa4f7347bc82ea83ed82d447f447dfe325 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin Date: Tue, 19 Apr 2022 23:01:09 +0300 Subject: [PATCH 071/237] [3.10] gh-91118: Fix docstrings that do not honor --without-doc-strings (GH-31769) (#91662) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Éric Co-authored-by: Jelle Zijlstra (cherry picked from commit a573cb2fec664c645ab744658d7e941d72e1a398) Co-authored-by: Oleg Iarygin --- Doc/c-api/typeobj.rst | 8 +-- Doc/extending/newtypes_tutorial.rst | 4 +- Doc/includes/custom.c | 2 +- Doc/includes/custom2.c | 2 +- Doc/includes/custom3.c | 2 +- Doc/includes/custom4.c | 2 +- Doc/includes/sublist.c | 2 +- .../2022-03-08-21-59-57.bpo-46962.UomDfz.rst | 10 ++++ .../2022-03-08-22-10-38.bpo-46962.FIVe9I.rst | 4 ++ Modules/_ctypes/_ctypes.c | 56 +++++++++---------- Modules/_ctypes/callbacks.c | 2 +- Modules/_ctypes/callproc.c | 32 +++++------ Modules/_ctypes/cfield.c | 2 +- Modules/_testcapimodule.c | 2 +- Objects/genericaliasobject.c | 10 ++-- Objects/picklebufobject.c | 2 +- Objects/unionobject.c | 4 +- 17 files changed, 81 insertions(+), 65 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-03-08-21-59-57.bpo-46962.UomDfz.rst create mode 100644 Misc/NEWS.d/next/Documentation/2022-03-08-22-10-38.bpo-46962.FIVe9I.rst diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 93492200ea44e7..d24eabe7e8d554 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -2596,7 +2596,7 @@ A basic :ref:`static type `:: PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "mymod.MyObject", .tp_basicsize = sizeof(MyObject), - .tp_doc = "My objects", + .tp_doc = PyDoc_STR("My objects"), .tp_new = myobj_new, .tp_dealloc = (destructor)myobj_dealloc, .tp_repr = (reprfunc)myobj_repr, @@ -2626,7 +2626,7 @@ with a more verbose initializer:: 0, /* tp_setattro */ 0, /* tp_as_buffer */ 0, /* tp_flags */ - "My objects", /* tp_doc */ + PyDoc_STR("My objects"), /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -2659,7 +2659,7 @@ A type that supports weakrefs, instance dicts, and hashing:: PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "mymod.MyObject", .tp_basicsize = sizeof(MyObject), - .tp_doc = "My objects", + .tp_doc = PyDoc_STR("My objects"), .tp_weaklistoffset = offsetof(MyObject, weakreflist), .tp_dictoffset = offsetof(MyObject, inst_dict), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, @@ -2687,7 +2687,7 @@ to create instances (e.g. uses a separate factory func) using .tp_name = "mymod.MyStr", .tp_basicsize = sizeof(MyStr), .tp_base = NULL, // set to &PyUnicode_Type in module init - .tp_doc = "my custom str", + .tp_doc = PyDoc_STR("my custom str"), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, .tp_repr = (reprfunc)myobj_repr, }; diff --git a/Doc/extending/newtypes_tutorial.rst b/Doc/extending/newtypes_tutorial.rst index 904915306f1f38..34c25d1f6f199c 100644 --- a/Doc/extending/newtypes_tutorial.rst +++ b/Doc/extending/newtypes_tutorial.rst @@ -90,7 +90,7 @@ The second bit is the definition of the type object. :: static PyTypeObject CustomType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "custom.Custom", - .tp_doc = "Custom objects", + .tp_doc = PyDoc_STR("Custom objects"), .tp_basicsize = sizeof(CustomObject), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT, @@ -161,7 +161,7 @@ you will need to OR the corresponding flags. We provide a doc string for the type in :c:member:`~PyTypeObject.tp_doc`. :: - .tp_doc = "Custom objects", + .tp_doc = PyDoc_STR("Custom objects"), To enable object creation, we have to provide a :c:member:`~PyTypeObject.tp_new` handler. This is the equivalent of the Python method :meth:`__new__`, but diff --git a/Doc/includes/custom.c b/Doc/includes/custom.c index f361baf830dd1b..26ca754964733d 100644 --- a/Doc/includes/custom.c +++ b/Doc/includes/custom.c @@ -9,7 +9,7 @@ typedef struct { static PyTypeObject CustomType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "custom.Custom", - .tp_doc = "Custom objects", + .tp_doc = PyDoc_STR("Custom objects"), .tp_basicsize = sizeof(CustomObject), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT, diff --git a/Doc/includes/custom2.c b/Doc/includes/custom2.c index 5bacab7a2a9714..2a3c59f8f04c3d 100644 --- a/Doc/includes/custom2.c +++ b/Doc/includes/custom2.c @@ -98,7 +98,7 @@ static PyMethodDef Custom_methods[] = { static PyTypeObject CustomType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "custom2.Custom", - .tp_doc = "Custom objects", + .tp_doc = PyDoc_STR("Custom objects"), .tp_basicsize = sizeof(CustomObject), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, diff --git a/Doc/includes/custom3.c b/Doc/includes/custom3.c index 2b7a99ecf96c76..5a47530f0a6b0d 100644 --- a/Doc/includes/custom3.c +++ b/Doc/includes/custom3.c @@ -148,7 +148,7 @@ static PyMethodDef Custom_methods[] = { static PyTypeObject CustomType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "custom3.Custom", - .tp_doc = "Custom objects", + .tp_doc = PyDoc_STR("Custom objects"), .tp_basicsize = sizeof(CustomObject), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, diff --git a/Doc/includes/custom4.c b/Doc/includes/custom4.c index 584992fc5f1a8a..c7ee55578488ed 100644 --- a/Doc/includes/custom4.c +++ b/Doc/includes/custom4.c @@ -160,7 +160,7 @@ static PyMethodDef Custom_methods[] = { static PyTypeObject CustomType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "custom4.Custom", - .tp_doc = "Custom objects", + .tp_doc = PyDoc_STR("Custom objects"), .tp_basicsize = sizeof(CustomObject), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, diff --git a/Doc/includes/sublist.c b/Doc/includes/sublist.c index b2c26e73ebaf7e..b36dadf07eae87 100644 --- a/Doc/includes/sublist.c +++ b/Doc/includes/sublist.c @@ -31,7 +31,7 @@ SubList_init(SubListObject *self, PyObject *args, PyObject *kwds) static PyTypeObject SubListType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "sublist.SubList", - .tp_doc = "SubList objects", + .tp_doc = PyDoc_STR("SubList objects"), .tp_basicsize = sizeof(SubListObject), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-08-21-59-57.bpo-46962.UomDfz.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-08-21-59-57.bpo-46962.UomDfz.rst new file mode 100644 index 00000000000000..395c9b3d8f5260 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-08-21-59-57.bpo-46962.UomDfz.rst @@ -0,0 +1,10 @@ +Classes and functions that unconditionally declared their docstrings +ignoring the `--without-doc-strings` compilation flag no longer do so. + +The classes affected are :class:`ctypes.UnionType`, +:class:`pickle.PickleBuffer`, :class:`testcapi.RecursingInfinitelyError`, +and :class:`types.GenericAlias`. + +The functions affected are 24 methods in :mod:`ctypes`. + +Patch by Oleg Iarygin. diff --git a/Misc/NEWS.d/next/Documentation/2022-03-08-22-10-38.bpo-46962.FIVe9I.rst b/Misc/NEWS.d/next/Documentation/2022-03-08-22-10-38.bpo-46962.FIVe9I.rst new file mode 100644 index 00000000000000..f5b54013bd6720 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-03-08-22-10-38.bpo-46962.FIVe9I.rst @@ -0,0 +1,4 @@ +All docstrings in code snippets are now wrapped into :func:`PyDoc_STR` to +follow the guideline of `PEP 7's Documentation Strings paragraph +`_. Patch +by Oleg Iarygin. diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 5f8a723f6373ae..84378c40357b07 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -187,7 +187,7 @@ static PyTypeObject DictRemover_Type = { 0, /* tp_as_buffer */ /* XXX should participate in GC? */ Py_TPFLAGS_DEFAULT, /* tp_flags */ - "deletes a key from a dictionary", /* tp_doc */ + PyDoc_STR("deletes a key from a dictionary"), /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -570,8 +570,8 @@ UnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return StructUnionType_new(type, args, kwds, 0); } -static const char from_address_doc[] = -"C.from_address(integer) -> C instance\naccess a C instance at the specified address"; +PyDoc_STRVAR(from_address_doc, +"C.from_address(integer) -> C instance\naccess a C instance at the specified address"); static PyObject * CDataType_from_address(PyObject *type, PyObject *value) @@ -588,8 +588,8 @@ CDataType_from_address(PyObject *type, PyObject *value) return PyCData_AtAddress(type, buf); } -static const char from_buffer_doc[] = -"C.from_buffer(object, offset=0) -> C instance\ncreate a C instance from a writeable buffer"; +PyDoc_STRVAR(from_buffer_doc, +"C.from_buffer(object, offset=0) -> C instance\ncreate a C instance from a writeable buffer"); static int KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep); @@ -668,8 +668,8 @@ CDataType_from_buffer(PyObject *type, PyObject *args) return result; } -static const char from_buffer_copy_doc[] = -"C.from_buffer_copy(object, offset=0) -> C instance\ncreate a C instance from a readable buffer"; +PyDoc_STRVAR(from_buffer_copy_doc, +"C.from_buffer_copy(object, offset=0) -> C instance\ncreate a C instance from a readable buffer"); static PyObject * GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds); @@ -719,8 +719,8 @@ CDataType_from_buffer_copy(PyObject *type, PyObject *args) return result; } -static const char in_dll_doc[] = -"C.in_dll(dll, name) -> C instance\naccess a C instance in a dll"; +PyDoc_STRVAR(in_dll_doc, +"C.in_dll(dll, name) -> C instance\naccess a C instance in a dll"); static PyObject * CDataType_in_dll(PyObject *type, PyObject *args) @@ -781,8 +781,8 @@ CDataType_in_dll(PyObject *type, PyObject *args) return PyCData_AtAddress(type, address); } -static const char from_param_doc[] = -"Convert a Python object into a function call parameter."; +PyDoc_STRVAR(from_param_doc, +"Convert a Python object into a function call parameter."); static PyObject * CDataType_from_param(PyObject *type, PyObject *value) @@ -936,7 +936,7 @@ PyTypeObject PyCStructType_Type = { PyCStructType_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - "metatype for the CData Objects", /* tp_doc */ + PyDoc_STR("metatype for the CData Objects"), /* tp_doc */ (traverseproc)CDataType_traverse, /* tp_traverse */ (inquiry)CDataType_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -978,7 +978,7 @@ static PyTypeObject UnionType_Type = { UnionType_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - "metatype for the CData Objects", /* tp_doc */ + PyDoc_STR("metatype for the CData Objects"), /* tp_doc */ (traverseproc)CDataType_traverse, /* tp_traverse */ (inquiry)CDataType_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -1236,7 +1236,7 @@ PyTypeObject PyCPointerType_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - "metatype for the Pointer Objects", /* tp_doc */ + PyDoc_STR("metatype for the Pointer Objects"), /* tp_doc */ (traverseproc)CDataType_traverse, /* tp_traverse */ (inquiry)CDataType_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -1648,7 +1648,7 @@ PyTypeObject PyCArrayType_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "metatype for the Array Objects", /* tp_doc */ + PyDoc_STR("metatype for the Array Objects"), /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -2342,7 +2342,7 @@ PyTypeObject PyCSimpleType_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "metatype for the PyCSimpleType Objects", /* tp_doc */ + PyDoc_STR("metatype for the PyCSimpleType Objects"), /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -2624,7 +2624,7 @@ PyTypeObject PyCFuncPtrType_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - "metatype for C function pointers", /* tp_doc */ + PyDoc_STR("metatype for C function pointers"), /* tp_doc */ (traverseproc)CDataType_traverse, /* tp_traverse */ (inquiry)CDataType_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -2929,7 +2929,7 @@ PyTypeObject PyCData_Type = { 0, /* tp_setattro */ &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "XXX to be provided", /* tp_doc */ + PyDoc_STR("XXX to be provided"), /* tp_doc */ (traverseproc)PyCData_traverse, /* tp_traverse */ (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -4327,7 +4327,7 @@ PyTypeObject PyCFuncPtr_Type = { 0, /* tp_setattro */ &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "Function Pointer", /* tp_doc */ + PyDoc_STR("Function Pointer"), /* tp_doc */ (traverseproc)PyCFuncPtr_traverse, /* tp_traverse */ (inquiry)PyCFuncPtr_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -4479,7 +4479,7 @@ static PyTypeObject Struct_Type = { 0, /* tp_setattro */ &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "Structure base class", /* tp_doc */ + PyDoc_STR("Structure base class"), /* tp_doc */ (traverseproc)PyCData_traverse, /* tp_traverse */ (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -4521,7 +4521,7 @@ static PyTypeObject Union_Type = { 0, /* tp_setattro */ &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "Union base class", /* tp_doc */ + PyDoc_STR("Union base class"), /* tp_doc */ (traverseproc)PyCData_traverse, /* tp_traverse */ (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -4841,7 +4841,7 @@ PyTypeObject PyCArray_Type = { 0, /* tp_setattro */ &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "XXX to be provided", /* tp_doc */ + PyDoc_STR("XXX to be provided"), /* tp_doc */ (traverseproc)PyCData_traverse, /* tp_traverse */ (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -5060,7 +5060,7 @@ static PyTypeObject Simple_Type = { 0, /* tp_setattro */ &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "XXX to be provided", /* tp_doc */ + PyDoc_STR("XXX to be provided"), /* tp_doc */ (traverseproc)PyCData_traverse, /* tp_traverse */ (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -5442,7 +5442,7 @@ PyTypeObject PyCPointer_Type = { 0, /* tp_setattro */ &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "XXX to be provided", /* tp_doc */ + PyDoc_STR("XXX to be provided"), /* tp_doc */ (traverseproc)PyCData_traverse, /* tp_traverse */ (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -5469,12 +5469,12 @@ PyTypeObject PyCPointer_Type = { * Module initialization. */ -static const char module_docs[] = -"Create and manipulate C compatible data types in Python."; +PyDoc_STRVAR(_ctypes__doc__, +"Create and manipulate C compatible data types in Python."); #ifdef MS_WIN32 -static const char comerror_doc[] = "Raised when a COM method call failed."; +PyDoc_STRVAR(comerror_doc, "Raised when a COM method call failed."); int comerror_init(PyObject *self, PyObject *args, PyObject *kwds) @@ -5663,7 +5663,7 @@ wstring_at(const wchar_t *ptr, int size) static struct PyModuleDef _ctypesmodule = { PyModuleDef_HEAD_INIT, .m_name = "_ctypes", - .m_doc = module_docs, + .m_doc = _ctypes__doc__, .m_size = -1, .m_methods = _ctypes_module_methods, }; diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index 5a4d1c543f1009..c0ff7891c9a47d 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -65,7 +65,7 @@ PyTypeObject PyCThunk_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - "CThunkObject", /* tp_doc */ + PyDoc_STR("CThunkObject"), /* tp_doc */ CThunkObject_traverse, /* tp_traverse */ CThunkObject_clear, /* tp_clear */ 0, /* tp_richcompare */ diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index ddf289e3e8f600..48694760dbedf1 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -1312,11 +1312,11 @@ _parse_voidp(PyObject *obj, void **address) #ifdef MS_WIN32 -static const char format_error_doc[] = +PyDoc_STRVAR(format_error_doc, "FormatError([integer]) -> string\n\ \n\ Convert a win32 error code into a string. If the error code is not\n\ -given, the return value of a call to GetLastError() is used.\n"; +given, the return value of a call to GetLastError() is used.\n"); static PyObject *format_error(PyObject *self, PyObject *args) { PyObject *result; @@ -1336,13 +1336,13 @@ static PyObject *format_error(PyObject *self, PyObject *args) return result; } -static const char load_library_doc[] = +PyDoc_STRVAR(load_library_doc, "LoadLibrary(name, load_flags) -> handle\n\ \n\ Load an executable (usually a DLL), and return a handle to it.\n\ The handle may be used to locate exported functions in this\n\ module. load_flags are as defined for LoadLibraryEx in the\n\ -Windows API.\n"; +Windows API.\n"); static PyObject *load_library(PyObject *self, PyObject *args) { PyObject *nameobj; @@ -1387,10 +1387,10 @@ static PyObject *load_library(PyObject *self, PyObject *args) #endif } -static const char free_library_doc[] = +PyDoc_STRVAR(free_library_doc, "FreeLibrary(handle) -> void\n\ \n\ -Free the handle of an executable previously loaded by LoadLibrary.\n"; +Free the handle of an executable previously loaded by LoadLibrary.\n"); static PyObject *free_library(PyObject *self, PyObject *args) { void *hMod; @@ -1410,8 +1410,8 @@ static PyObject *free_library(PyObject *self, PyObject *args) Py_RETURN_NONE; } -static const char copy_com_pointer_doc[] = -"CopyComPointer(src, dst) -> HRESULT value\n"; +PyDoc_STRVAR(copy_com_pointer_doc, +"CopyComPointer(src, dst) -> HRESULT value\n"); static PyObject * copy_com_pointer(PyObject *self, PyObject *args) @@ -1649,10 +1649,10 @@ call_cdeclfunction(PyObject *self, PyObject *args) /***************************************************************** * functions */ -static const char sizeof_doc[] = +PyDoc_STRVAR(sizeof_doc, "sizeof(C type) -> integer\n" "sizeof(C instance) -> integer\n" -"Return the size in bytes of a C instance"; +"Return the size in bytes of a C instance"); static PyObject * sizeof_func(PyObject *self, PyObject *obj) @@ -1670,10 +1670,10 @@ sizeof_func(PyObject *self, PyObject *obj) return NULL; } -static const char alignment_doc[] = +PyDoc_STRVAR(alignment_doc, "alignment(C type) -> integer\n" "alignment(C instance) -> integer\n" -"Return the alignment requirements of a C instance"; +"Return the alignment requirements of a C instance"); static PyObject * align_func(PyObject *self, PyObject *obj) @@ -1693,10 +1693,10 @@ align_func(PyObject *self, PyObject *obj) return NULL; } -static const char byref_doc[] = +PyDoc_STRVAR(byref_doc, "byref(C instance[, offset=0]) -> byref-object\n" "Return a pointer lookalike to a C instance, only usable\n" -"as function argument"; +"as function argument"); /* * We must return something which can be converted to a parameter, @@ -1737,9 +1737,9 @@ byref(PyObject *self, PyObject *args) return (PyObject *)parg; } -static const char addressof_doc[] = +PyDoc_STRVAR(addressof_doc, "addressof(C instance) -> integer\n" -"Return the address of the C instance internal buffer"; +"Return the address of the C instance internal buffer"); static PyObject * addressof(PyObject *self, PyObject *obj) diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index ec6feca8b0f809..534ec944001283 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -318,7 +318,7 @@ PyTypeObject PyCField_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - "Structure/Union member", /* tp_doc */ + PyDoc_STR("Structure/Union member"), /* tp_doc */ (traverseproc)PyCField_traverse, /* tp_traverse */ (inquiry)PyCField_clear, /* tp_clear */ 0, /* tp_richcompare */ diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index c5c942820b66fa..aaf29ad0115441 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -6287,7 +6287,7 @@ static PyTypeObject PyRecursingInfinitelyError_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "Instantiating this exception starts infinite recursion.", /* tp_doc */ + PyDoc_STR("Instantiating this exception starts infinite recursion."), /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ diff --git a/Objects/genericaliasobject.c b/Objects/genericaliasobject.c index dbe5d89b739629..f52bc974f4d810 100644 --- a/Objects/genericaliasobject.c +++ b/Objects/genericaliasobject.c @@ -349,6 +349,11 @@ _Py_subs_parameters(PyObject *self, PyObject *args, PyObject *parameters, PyObje return newargs; } +PyDoc_STRVAR(genericalias__doc__, +"Represent a PEP 585 generic type\n" +"\n" +"E.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,)."); + static PyObject * ga_getitem(PyObject *self, PyObject *item) { @@ -628,14 +633,11 @@ static PyNumberMethods ga_as_number = { // TODO: // - argument clinic? -// - __doc__? // - cache? PyTypeObject Py_GenericAliasType = { PyVarObject_HEAD_INIT(&PyType_Type, 0) .tp_name = "types.GenericAlias", - .tp_doc = "Represent a PEP 585 generic type\n" - "\n" - "E.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + .tp_doc = genericalias__doc__, .tp_basicsize = sizeof(gaobject), .tp_dealloc = ga_dealloc, .tp_repr = ga_repr, diff --git a/Objects/picklebufobject.c b/Objects/picklebufobject.c index a135e5575e28c5..aaa852cfbb05b0 100644 --- a/Objects/picklebufobject.c +++ b/Objects/picklebufobject.c @@ -206,7 +206,7 @@ static PyMethodDef picklebuf_methods[] = { PyTypeObject PyPickleBuffer_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "pickle.PickleBuffer", - .tp_doc = "Wrapper for potentially out-of-band buffers", + .tp_doc = PyDoc_STR("Wrapper for potentially out-of-band buffers"), .tp_basicsize = sizeof(PyPickleBufferObject), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_new = picklebuf_new, diff --git a/Objects/unionobject.c b/Objects/unionobject.c index 80c70389ab30d6..6d8bb02142192b 100644 --- a/Objects/unionobject.c +++ b/Objects/unionobject.c @@ -447,9 +447,9 @@ union_getattro(PyObject *self, PyObject *name) PyTypeObject _PyUnion_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) .tp_name = "types.UnionType", - .tp_doc = "Represent a PEP 604 union type\n" + .tp_doc = PyDoc_STR("Represent a PEP 604 union type\n" "\n" - "E.g. for int | str", + "E.g. for int | str"), .tp_basicsize = sizeof(unionobject), .tp_dealloc = unionobject_dealloc, .tp_alloc = PyType_GenericAlloc, From 68caef8f8e4c127c188a741fbebdf4cf077b0f93 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 19 Apr 2022 13:41:39 -0700 Subject: [PATCH 072/237] build(deps): bump actions/setup-python from 2 to 3 (GH-31630) Bumps [actions/setup-python](https://github.com/actions/setup-python) from 2 to 3. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jelle Zijlstra (cherry picked from commit 74e319239b0a2a5ef8bc27670f4f533ee701d57f) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8bd506c9f3135a..43b4f769376578 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -82,7 +82,7 @@ jobs: if: needs.check_source.outputs.run_tests == 'true' steps: - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v3 - name: Install Dependencies run: sudo ./.github/workflows/posix-deps-apt.sh - name: Add ccache to PATH From e08d32381d749bc4f3e4302e067076fa8c4e0661 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 19 Apr 2022 18:20:03 -0700 Subject: [PATCH 073/237] gh-87497: Document that urllib.request sends headers in camel case (GH-24661) (#91517) Co-authored-by: Jelle Zijlstra (cherry picked from commit 325d6f50357474c7d9fd2475be0e2481f7ae0476) Co-authored-by: Alix Lourme --- Doc/library/urllib.request.rst | 1 + Lib/test/test_urllib2_localnet.py | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index 659a3632ac9be8..9573683dd05944 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -218,6 +218,7 @@ The following classes are provided: (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11"``, while :mod:`urllib`'s default user agent string is ``"Python-urllib/2.6"`` (on Python 2.6). + All header keys are sent in camel case. An appropriate ``Content-Type`` header should be included if the *data* argument is present. If this header has not been provided and *data* diff --git a/Lib/test/test_urllib2_localnet.py b/Lib/test/test_urllib2_localnet.py index 1b2baf2f366b56..fe2ff81a24e694 100644 --- a/Lib/test/test_urllib2_localnet.py +++ b/Lib/test/test_urllib2_localnet.py @@ -614,6 +614,15 @@ def test_sending_headers(self): pass self.assertEqual(handler.headers_received["Range"], "bytes=20-39") + def test_sending_headers_camel(self): + handler = self.start_server() + req = urllib.request.Request("http://localhost:%s/" % handler.port, + headers={"X-SoMe-hEader": "foobar"}) + with urllib.request.urlopen(req): + pass + self.assertIn("X-Some-Header", handler.headers_received.keys()) + self.assertNotIn("X-SoMe-hEader", handler.headers_received.keys()) + def test_basic(self): handler = self.start_server() with urllib.request.urlopen("http://localhost:%s" % handler.port) as open_url: From f92aa4fde1728ed47dd6dc64206dcdcabd81d1fc Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 19 Apr 2022 18:38:15 -0700 Subject: [PATCH 074/237] Fix awkward sentence in signal docs (GH-91508) Co-authored-by: Jelle Zijlstra (cherry picked from commit 326ae71f1d93c12100150baa1173ea7ce7a96ea0) Co-authored-by: AJ Jordan --- Doc/library/signal.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index 11bdfc8e82831d..0aa5996b89423b 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -676,10 +676,11 @@ case, wrap your entry point to catch this exception as follows:: if __name__ == '__main__': main() -Do not set :const:`SIGPIPE`'s disposition to :const:`SIG_DFL` -in order to avoid :exc:`BrokenPipeError`. Doing that would cause -your program to exit unexpectedly also whenever any socket connection -is interrupted while your program is still writing to it. +Do not set :const:`SIGPIPE`'s disposition to :const:`SIG_DFL` in +order to avoid :exc:`BrokenPipeError`. Doing that would cause +your program to exit unexpectedly whenever any socket +connection is interrupted while your program is still writing to +it. .. _handlers-and-exceptions: From 8299e24d4caa392664648fc5c65f4e56a40d6d46 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 19 Apr 2022 21:17:34 -0700 Subject: [PATCH 075/237] Add link to sys.path in os lib (GH-91679) (cherry picked from commit 692aea6f3823df48b7fc267ba0aa1ccc45ac606d) Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> --- Doc/library/os.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 203995c80fd327..dbd3c968dd35ac 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -3546,8 +3546,8 @@ to be ignored. Add a path to the DLL search path. This search path is used when resolving dependencies for imported - extension modules (the module itself is resolved through sys.path), - and also by :mod:`ctypes`. + extension modules (the module itself is resolved through + :data:`sys.path`), and also by :mod:`ctypes`. Remove the directory by calling **close()** on the returned object or using it in a :keyword:`with` statement. From 942ea19cf956a2352bd82cc43fb4c1723ba72867 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Wed, 20 Apr 2022 12:57:30 +0700 Subject: [PATCH 076/237] Fix whitespace/indentation issues in test_sys (GH-32369) (GH-32372) --- Lib/test/test_sys.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 35da72c432b0af..a0458092553b4c 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1078,8 +1078,8 @@ class X(Exception): with test.support.captured_stderr() as stderr, \ test.support.swap_attr(sys, 'unraisablehook', sys.__unraisablehook__): - expected = self.write_unraisable_exc( - A.B.X(), "msg", "obj"); + expected = self.write_unraisable_exc( + A.B.X(), "msg", "obj"); report = stderr.getvalue() testName = 'test_original_unraisablehook_exception_qualname' self.assertIn(f"{testName}..A.B.X", report) From 88bbc5dd7af2efa74989f23689438d5113521798 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 20 Apr 2022 02:00:43 -0700 Subject: [PATCH 077/237] bpo-30718: Add information about text buffering (GH-32351) (cherry picked from commit 5101d97d0b13425ccc5ed37abfabb07701db81fe) Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> --- Doc/library/functions.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 95231363a5dc2e..42fbf4e6f969cd 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -1168,7 +1168,11 @@ are always available. They are listed here in alphabetical order. *buffering* is an optional integer used to set the buffering policy. Pass 0 to switch buffering off (only allowed in binary mode), 1 to select line buffering (only usable in text mode), and an integer > 1 to indicate the size - in bytes of a fixed-size chunk buffer. When no *buffering* argument is + in bytes of a fixed-size chunk buffer. Note that specifying a buffer size this + way applies for binary buffered I/O, but ``TextIOWrapper`` (i.e., files opened + with ``mode='r+'``) would have another buffering. To disable buffering in + ``TextIOWrapper``, consider using the ``write_through`` flag for + :func:`io.TextIOWrapper.reconfigure`. When no *buffering* argument is given, the default buffering policy works as follows: * Binary files are buffered in fixed-size chunks; the size of the buffer is From 923ef87c77d4e0ea54fa03eae6928b42b9094e8d Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 20 Apr 2022 04:06:29 -0700 Subject: [PATCH 078/237] gh-91734: Fix ossaudio support on Solaris (GH-91735) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 4420faf273e9e2d03226a9375e1e04a336230c84) Co-authored-by: Jakub Kulík --- .../Library/2022-04-20-09-49-33.gh-issue-91734.4Dj4Gy.rst | 1 + Modules/ossaudiodev.c | 4 ++++ 2 files changed, 5 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2022-04-20-09-49-33.gh-issue-91734.4Dj4Gy.rst diff --git a/Misc/NEWS.d/next/Library/2022-04-20-09-49-33.gh-issue-91734.4Dj4Gy.rst b/Misc/NEWS.d/next/Library/2022-04-20-09-49-33.gh-issue-91734.4Dj4Gy.rst new file mode 100644 index 00000000000000..47d9e0dea458a3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-20-09-49-33.gh-issue-91734.4Dj4Gy.rst @@ -0,0 +1 @@ +Fix OSS audio support on Solaris. diff --git a/Modules/ossaudiodev.c b/Modules/ossaudiodev.c index 4f2d9cb8b7c9c7..b22bd42dcaa6f5 100644 --- a/Modules/ossaudiodev.c +++ b/Modules/ossaudiodev.c @@ -1243,8 +1243,12 @@ PyInit_ossaudiodev(void) _EXPORT_INT(m, SNDCTL_DSP_GETSPDIF); #endif _EXPORT_INT(m, SNDCTL_DSP_GETTRIGGER); +#ifdef SNDCTL_DSP_MAPINBUF _EXPORT_INT(m, SNDCTL_DSP_MAPINBUF); +#endif +#ifdef SNDCTL_DSP_MAPOUTBUF _EXPORT_INT(m, SNDCTL_DSP_MAPOUTBUF); +#endif _EXPORT_INT(m, SNDCTL_DSP_NONBLOCK); _EXPORT_INT(m, SNDCTL_DSP_POST); #ifdef SNDCTL_DSP_PROFILE From 73af4b0264aeb866536b01a132f8c26a5808d64d Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Wed, 20 Apr 2022 14:30:16 +0100 Subject: [PATCH 079/237] bpo-40859: Update Windows build to use xz-5.2.5 (GH-20622) Co-authored-by: Ma Lin --- .../next/Windows/2020-06-04-10-42-04.bpo-40859.isKSw7.rst | 1 + PCbuild/get_externals.bat | 2 +- PCbuild/liblzma.vcxproj | 4 ++-- PCbuild/liblzma.vcxproj.filters | 2 +- PCbuild/python.props | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2020-06-04-10-42-04.bpo-40859.isKSw7.rst diff --git a/Misc/NEWS.d/next/Windows/2020-06-04-10-42-04.bpo-40859.isKSw7.rst b/Misc/NEWS.d/next/Windows/2020-06-04-10-42-04.bpo-40859.isKSw7.rst new file mode 100644 index 00000000000000..ef4c727ad28661 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2020-06-04-10-42-04.bpo-40859.isKSw7.rst @@ -0,0 +1 @@ +Update Windows build to use xz-5.2.5 diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index dc5c909de74418..ee79addd44d02b 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -58,7 +58,7 @@ set libraries=%libraries% sqlite-3.37.2.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.12.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.12.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tix-8.4.3.6 -set libraries=%libraries% xz-5.2.2 +set libraries=%libraries% xz-5.2.5 set libraries=%libraries% zlib-1.2.12 for %%e in (%libraries%) do ( diff --git a/PCbuild/liblzma.vcxproj b/PCbuild/liblzma.vcxproj index a6bd59ec0baa3d..4dd42ab98a9759 100644 --- a/PCbuild/liblzma.vcxproj +++ b/PCbuild/liblzma.vcxproj @@ -92,7 +92,7 @@ WIN32;HAVE_CONFIG_H;_LIB;%(PreprocessorDefinitions) - $(lzmaDir)windows;$(lzmaDir)src/liblzma/common;$(lzmaDir)src/common;$(lzmaDir)src/liblzma/api;$(lzmaDir)src/liblzma/check;$(lzmaDir)src/liblzma/delta;$(lzmaDir)src/liblzma/lz;$(lzmaDir)src/liblzma/lzma;$(lzmaDir)src/liblzma/rangecoder;$(lzmaDir)src/liblzma/simple;%(AdditionalIncludeDirectories) + $(lzmaDir)windows/vs2019;$(lzmaDir)src/liblzma/common;$(lzmaDir)src/common;$(lzmaDir)src/liblzma/api;$(lzmaDir)src/liblzma/check;$(lzmaDir)src/liblzma/delta;$(lzmaDir)src/liblzma/lz;$(lzmaDir)src/liblzma/lzma;$(lzmaDir)src/liblzma/rangecoder;$(lzmaDir)src/liblzma/simple;%(AdditionalIncludeDirectories) 4028;4113;4133;4244;4267;4996;%(DisableSpecificWarnings) @@ -238,7 +238,7 @@ - + diff --git a/PCbuild/liblzma.vcxproj.filters b/PCbuild/liblzma.vcxproj.filters index 3f58351fa9edb6..ebe2a7d5fa9e5d 100644 --- a/PCbuild/liblzma.vcxproj.filters +++ b/PCbuild/liblzma.vcxproj.filters @@ -428,7 +428,7 @@ Header Files - + Header Files diff --git a/PCbuild/python.props b/PCbuild/python.props index 7b42037b7cdf87..c451429da2c827 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -59,7 +59,7 @@ $(ExternalsDir)\ $(ExternalsDir)sqlite-3.37.2.0\ $(ExternalsDir)bzip2-1.0.8\ - $(ExternalsDir)xz-5.2.2\ + $(ExternalsDir)xz-5.2.5\ $(ExternalsDir)libffi-3.3.0\ $(ExternalsDir)libffi-3.3.0\$(ArchName)\ $(libffiOutDir)include From c33524e68b853b8b313536af1b7092efd53e5d15 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Wed, 20 Apr 2022 07:40:36 -0700 Subject: [PATCH 080/237] [3.10] build(deps): bump actions/checkout from 2 to 3 (GH-32226) (#91723) Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>. (cherry picked from commit 1ba63e3a9bb176e5ad8e8dd744b9d2b9d588e275) --- .github/workflows/build.yml | 14 +++++++------- .github/workflows/build_msi.yml | 4 ++-- .github/workflows/doc.yml | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 43b4f769376578..ce300ebe59bfac 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,7 +27,7 @@ jobs: run_tests: ${{ steps.check.outputs.run_tests }} run_ssl_tests: ${{ steps.check.outputs.run_ssl_tests }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Check for source changes id: check run: | @@ -81,7 +81,7 @@ jobs: needs: check_source if: needs.check_source.outputs.run_tests == 'true' steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: actions/setup-python@v3 - name: Install Dependencies run: sudo ./.github/workflows/posix-deps-apt.sh @@ -127,7 +127,7 @@ jobs: env: IncludeUwp: 'true' steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Build CPython run: .\PCbuild\build.bat -e -p Win32 - name: Display build info @@ -143,7 +143,7 @@ jobs: env: IncludeUwp: 'true' steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Register MSVC problem matcher run: echo "::add-matcher::.github/problem-matchers/msvc.json" - name: Build CPython @@ -161,7 +161,7 @@ jobs: env: PYTHONSTRICTEXTENSIONBUILD: 1 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Prepare homebrew environment variables run: | echo "LDFLAGS=-L$(brew --prefix tcl-tk)/lib" >> $GITHUB_ENV @@ -184,7 +184,7 @@ jobs: OPENSSL_VER: 1.1.1n PYTHONSTRICTEXTENSIONBUILD: 1 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Register gcc problem matcher run: echo "::add-matcher::.github/problem-matchers/gcc.json" - name: Install Dependencies @@ -232,7 +232,7 @@ jobs: OPENSSL_DIR: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }} LD_LIBRARY_PATH: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }}/lib steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Register gcc problem matcher run: echo "::add-matcher::.github/problem-matchers/gcc.json" - name: Install Dependencies diff --git a/.github/workflows/build_msi.yml b/.github/workflows/build_msi.yml index 28ce06f3cf4e08..201098a635799a 100644 --- a/.github/workflows/build_msi.yml +++ b/.github/workflows/build_msi.yml @@ -25,7 +25,7 @@ jobs: name: 'Windows (x86) Installer' runs-on: windows-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Build CPython installer run: .\Tools\msi\build.bat -x86 @@ -33,6 +33,6 @@ jobs: name: 'Windows (x64) Installer' runs-on: windows-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Build CPython installer run: .\Tools\msi\build.bat -x64 diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index 4426238b9d9fa0..970f5af2d9bed3 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -25,7 +25,7 @@ jobs: name: 'Docs' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Register Sphinx problem matcher run: echo "::add-matcher::.github/problem-matchers/sphinx.json" - name: 'Install Dependencies' From 886b22c4c3c5324bcebb79402c92d18ebc4224b6 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 20 Apr 2022 09:41:12 -0700 Subject: [PATCH 081/237] bpo-23747: Enhance platform doc, document default behavior (GH-31462) (cherry picked from commit ad3ca17ff5cd63f907430073b52be27695674148) Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> --- Doc/library/platform.rst | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Doc/library/platform.rst b/Doc/library/platform.rst index a0eece6c4d8aa0..346063d66afab9 100644 --- a/Doc/library/platform.rst +++ b/Doc/library/platform.rst @@ -139,7 +139,7 @@ Cross Platform .. function:: release() - Returns the system's release, e.g. ``'2.2.0'`` or ``'NT'`` An empty string is + Returns the system's release, e.g. ``'2.2.0'`` or ``'NT'``. An empty string is returned if the value cannot be determined. @@ -176,7 +176,7 @@ Cross Platform Entries which cannot be determined are set to ``''``. .. versionchanged:: 3.3 - Result changed from a tuple to a namedtuple. + Result changed from a tuple to a :func:`~collections.namedtuple`. Java Platform @@ -201,7 +201,9 @@ Windows Platform Get additional version information from the Windows Registry and return a tuple ``(release, version, csd, ptype)`` referring to OS release, version number, - CSD level (service pack) and OS type (multi/single processor). + CSD level (service pack) and OS type (multi/single processor). Values which + cannot be determined are set to the defaults given as parameters (which all + default to an empty string). As a hint: *ptype* is ``'Uniprocessor Free'`` on single processor NT machines and ``'Multiprocessor Free'`` on multi processor machines. The *'Free'* refers @@ -211,9 +213,9 @@ Windows Platform .. function:: win32_edition() - Returns a string representing the current Windows edition. Possible - values include but are not limited to ``'Enterprise'``, ``'IoTUAP'``, - ``'ServerStandard'``, and ``'nanoserver'``. + Returns a string representing the current Windows edition, or ``None`` if the + value cannot be determined. Possible values include but are not limited to + ``'Enterprise'``, ``'IoTUAP'``, ``'ServerStandard'``, and ``'nanoserver'``. .. versionadded:: 3.8 From d8d5db5f1024f2f902c489be74d4ae713c59c748 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Wed, 20 Apr 2022 18:53:05 -0700 Subject: [PATCH 082/237] [3.10] build(deps): bump actions/cache from 2.1.7 to 3.0.1 (GH-32228) (#91746) Bumps [actions/cache](https://github.com/actions/cache) from 2.1.7 to 3.0.1. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v2.1.7...v3.0.1) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jelle Zijlstra . (cherry picked from commit 3ace1034b8202bc7034e15f34561725934f04ff6) --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ce300ebe59bfac..adbe2fe1d248c1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -196,7 +196,7 @@ jobs: echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV - name: 'Restore OpenSSL build' id: cache-openssl - uses: actions/cache@v2.1.4 + uses: actions/cache@v3.0.1 with: path: ./multissl/openssl/${{ env.OPENSSL_VER }} key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} @@ -244,7 +244,7 @@ jobs: echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV - name: 'Restore OpenSSL build' id: cache-openssl - uses: actions/cache@v2.1.4 + uses: actions/cache@v3.0.1 with: path: ./multissl/openssl/${{ env.OPENSSL_VER }} key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} From 9f8b9a3506fefeba01a18eda0e06c037393be4bf Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Wed, 20 Apr 2022 18:53:31 -0700 Subject: [PATCH 083/237] [3.10] build(deps): bump actions/upload-artifact from 2.3.1 to 3 (GH-32227) (#91748) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 2.3.1 to 3. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v2.3.1...v3) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jelle Zijlstra . (cherry picked from commit b8812c9ca3f6864a233574001e16f1b9e92daf6e) --- .github/workflows/doc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index 970f5af2d9bed3..a57552b07905f4 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -39,7 +39,7 @@ jobs: - name: 'Build documentation' run: xvfb-run make -C Doc/ PYTHON=../python SPHINXOPTS="-q -W --keep-going -j4" doctest html suspicious - name: 'Upload' - uses: actions/upload-artifact@v2.2.2 + uses: actions/upload-artifact@v3 with: name: doc-html path: Doc/build/html From 9c18d783c38fca57a63b61aa778d8a8d18945d95 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 22 Apr 2022 21:08:49 +0300 Subject: [PATCH 084/237] [3.10] gh-90568: Fix exception type for \N with a named sequence in RE (GH-91665) (GH-91830) re.error is now raised instead of TypeError. (cherry picked from commit 6ccfa31421393910b52936e0447625db06f2a655) --- Lib/sre_parse.py | 4 ++-- Lib/test/test_re.py | 4 ++++ .../Library/2022-04-18-16-31-33.gh-issue-90568.9kiU7o.rst | 3 +++ 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-04-18-16-31-33.gh-issue-90568.9kiU7o.rst diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py index 53706676e9f7b8..d3ff196032b300 100644 --- a/Lib/sre_parse.py +++ b/Lib/sre_parse.py @@ -330,7 +330,7 @@ def _class_escape(source, escape): charname = source.getuntil('}', 'character name') try: c = ord(unicodedata.lookup(charname)) - except KeyError: + except (KeyError, TypeError): raise source.error("undefined character name %r" % charname, len(charname) + len(r'\N{}')) return LITERAL, c @@ -390,7 +390,7 @@ def _escape(source, escape, state): charname = source.getuntil('}', 'character name') try: c = ord(unicodedata.lookup(charname)) - except KeyError: + except (KeyError, TypeError): raise source.error("undefined character name %r" % charname, len(charname) + len(r'\N{}')) return LITERAL, c diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 9e5223a125b052..305ec8eef326b8 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -754,6 +754,10 @@ def test_named_unicode_escapes(self): "undefined character name 'SPAM'", 0) self.checkPatternError(r'[\N{SPAM}]', "undefined character name 'SPAM'", 1) + self.checkPatternError(r'\N{KEYCAP NUMBER SIGN}', + "undefined character name 'KEYCAP NUMBER SIGN'", 0) + self.checkPatternError(r'[\N{KEYCAP NUMBER SIGN}]', + "undefined character name 'KEYCAP NUMBER SIGN'", 1) self.checkPatternError(br'\N{LESS-THAN SIGN}', r'bad escape \N', 0) self.checkPatternError(br'[\N{LESS-THAN SIGN}]', r'bad escape \N', 1) diff --git a/Misc/NEWS.d/next/Library/2022-04-18-16-31-33.gh-issue-90568.9kiU7o.rst b/Misc/NEWS.d/next/Library/2022-04-18-16-31-33.gh-issue-90568.9kiU7o.rst new file mode 100644 index 00000000000000..4411c715830e2e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-18-16-31-33.gh-issue-90568.9kiU7o.rst @@ -0,0 +1,3 @@ +Parsing ``\N`` escapes of Unicode Named Character Sequences in a +:mod:`regular expression ` raises now :exc:`re.error` instead of +``TypeError``. From 080781cd49b13da4a73db87b6f5e0c7aeec83e92 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 22 Apr 2022 21:09:30 +0300 Subject: [PATCH 085/237] [3.10] gh-91700: Validate the group number in conditional expression in RE (GH-91702) (GH-91831) In expression (?(group)...) an appropriate re.error is now raised if the group number refers to not defined group. Previously it raised RuntimeError: invalid SRE code. (cherry picked from commit 48ec61a89a959071206549819448405c2cea61b0) --- Lib/sre_parse.py | 10 ++++++++++ Lib/test/test_re.py | 2 ++ .../2022-04-19-17-30-17.gh-issue-91700.MRJi6m.rst | 4 ++++ 3 files changed, 16 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2022-04-19-17-30-17.gh-issue-91700.MRJi6m.rst diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py index d3ff196032b300..20a602501191f6 100644 --- a/Lib/sre_parse.py +++ b/Lib/sre_parse.py @@ -78,6 +78,7 @@ def __init__(self): self.groupdict = {} self.groupwidths = [None] # group 0 self.lookbehindgroups = None + self.grouprefpos = {} @property def groups(self): return len(self.groupwidths) @@ -786,6 +787,10 @@ def _parse(source, state, verbose, nested, first=False): if condgroup >= MAXGROUPS: msg = "invalid group reference %d" % condgroup raise source.error(msg, len(condname) + 1) + if condgroup not in state.grouprefpos: + state.grouprefpos[condgroup] = ( + source.tell() - len(condname) - 1 + ) state.checklookbehindgroup(condgroup, source) item_yes = _parse(source, state, verbose, nested + 1) if source.match("|"): @@ -963,6 +968,11 @@ def parse(str, flags=0, state=None): assert source.next == ")" raise source.error("unbalanced parenthesis") + for g in p.state.grouprefpos: + if g >= p.state.groups: + msg = "invalid group reference %d" % g + raise error(msg, str, p.state.grouprefpos[g]) + if flags & SRE_FLAG_DEBUG: p.dump() diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 305ec8eef326b8..887ab781fc9d40 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -575,6 +575,8 @@ def test_re_groupref_exists_errors(self): self.checkPatternError(r'()(?(1)a|b|c)', 'conditional backref with more than ' 'two branches', 10) + self.checkPatternError(r'()(?(2)a)', + "invalid group reference 2", 5) def test_re_groupref_overflow(self): from sre_constants import MAXGROUPS diff --git a/Misc/NEWS.d/next/Library/2022-04-19-17-30-17.gh-issue-91700.MRJi6m.rst b/Misc/NEWS.d/next/Library/2022-04-19-17-30-17.gh-issue-91700.MRJi6m.rst new file mode 100644 index 00000000000000..73b106869697ba --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-19-17-30-17.gh-issue-91700.MRJi6m.rst @@ -0,0 +1,4 @@ +Compilation of regular expression containing a conditional expression +``(?(group)...)`` now raises an appropriate :exc:`re.error` if the group +number refers to not defined group. Previously an internal RuntimeError was +raised. From 1748816e80b23744667e239b49b477c0e283d201 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 22 Apr 2022 21:44:05 +0300 Subject: [PATCH 086/237] [3.10] gh-91575: Update case-insensitive matching in re to the latest Unicode version (GH-91580). (GH-91661) (cherry picked from commit 1c2fcebf3c5e2ab41d376bb481834445617c8f3c) --- Lib/sre_compile.py | 30 +++++++++- Lib/test/test_re.py | 55 +++++++++++++++++-- ...2-04-15-18-38-21.gh-issue-91575.fSyAxS.rst | 2 + 3 files changed, 78 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-04-15-18-38-21.gh-issue-91575.fSyAxS.rst diff --git a/Lib/sre_compile.py b/Lib/sre_compile.py index c6398bfb83a576..aed752d11d2e5e 100644 --- a/Lib/sre_compile.py +++ b/Lib/sre_compile.py @@ -52,6 +52,22 @@ (0x3c2, 0x3c3), # ςσ # GREEK SMALL LETTER PHI, GREEK PHI SYMBOL (0x3c6, 0x3d5), # φϕ + # CYRILLIC SMALL LETTER VE, CYRILLIC SMALL LETTER ROUNDED VE + (0x432, 0x1c80), # вᲀ + # CYRILLIC SMALL LETTER DE, CYRILLIC SMALL LETTER LONG-LEGGED DE + (0x434, 0x1c81), # дᲁ + # CYRILLIC SMALL LETTER O, CYRILLIC SMALL LETTER NARROW O + (0x43e, 0x1c82), # оᲂ + # CYRILLIC SMALL LETTER ES, CYRILLIC SMALL LETTER WIDE ES + (0x441, 0x1c83), # сᲃ + # CYRILLIC SMALL LETTER TE, CYRILLIC SMALL LETTER TALL TE, CYRILLIC SMALL LETTER THREE-LEGGED TE + (0x442, 0x1c84, 0x1c85), # тᲄᲅ + # CYRILLIC SMALL LETTER HARD SIGN, CYRILLIC SMALL LETTER TALL HARD SIGN + (0x44a, 0x1c86), # ъᲆ + # CYRILLIC SMALL LETTER YAT, CYRILLIC SMALL LETTER TALL YAT + (0x463, 0x1c87), # ѣᲇ + # CYRILLIC SMALL LETTER UNBLENDED UK, CYRILLIC SMALL LETTER MONOGRAPH UK + (0x1c88, 0xa64b), # ᲈꙋ # LATIN SMALL LETTER S WITH DOT ABOVE, LATIN SMALL LETTER LONG S WITH DOT ABOVE (0x1e61, 0x1e9b), # ṡẛ # LATIN SMALL LIGATURE LONG S T, LATIN SMALL LIGATURE ST @@ -320,11 +336,19 @@ def _optimize_charset(charset, iscased=None, fixup=None, fixes=None): charmap += b'\0' * 0xff00 continue # Character set contains non-BMP character codes. + # For range, all BMP characters in the range are already + # proceeded. if fixup: hascased = True - # There are only two ranges of cased non-BMP characters: - # 10400-1044F (Deseret) and 118A0-118DF (Warang Citi), - # and for both ranges RANGE_UNI_IGNORE works. + # For now, IN_UNI_IGNORE+LITERAL and + # IN_UNI_IGNORE+RANGE_UNI_IGNORE work for all non-BMP + # characters, because two characters (at least one of + # which is not in the BMP) match case-insensitively + # if and only if: + # 1) c1.lower() == c2.lower() + # 2) c1.lower() == c2 or c1.lower().upper() == c2 + # Also, both c.lower() and c.lower().upper() are single + # characters for every non-BMP character. if op is RANGE: op = RANGE_UNI_IGNORE tail.append((op, av)) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 887ab781fc9d40..3d6623b596ef90 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -873,16 +873,30 @@ def test_ignore_case(self): self.assertEqual(re.match(r"((a)\s(abc|a))", "a a", re.I).group(1), "a a") self.assertEqual(re.match(r"((a)\s(abc|a)*)", "a aa", re.I).group(1), "a aa") - assert '\u212a'.lower() == 'k' # 'K' + # Two different characters have the same lowercase. + assert 'K'.lower() == '\u212a'.lower() == 'k' # 'K' self.assertTrue(re.match(r'K', '\u212a', re.I)) self.assertTrue(re.match(r'k', '\u212a', re.I)) self.assertTrue(re.match(r'\u212a', 'K', re.I)) self.assertTrue(re.match(r'\u212a', 'k', re.I)) - assert '\u017f'.upper() == 'S' # 'ſ' + + # Two different characters have the same uppercase. + assert 's'.upper() == '\u017f'.upper() == 'S' # 'ſ' self.assertTrue(re.match(r'S', '\u017f', re.I)) self.assertTrue(re.match(r's', '\u017f', re.I)) self.assertTrue(re.match(r'\u017f', 'S', re.I)) self.assertTrue(re.match(r'\u017f', 's', re.I)) + + # Two different characters have the same uppercase. Unicode 9.0+. + assert '\u0432'.upper() == '\u1c80'.upper() == '\u0412' # 'в', 'ᲀ', 'В' + self.assertTrue(re.match(r'\u0412', '\u0432', re.I)) + self.assertTrue(re.match(r'\u0412', '\u1c80', re.I)) + self.assertTrue(re.match(r'\u0432', '\u0412', re.I)) + self.assertTrue(re.match(r'\u0432', '\u1c80', re.I)) + self.assertTrue(re.match(r'\u1c80', '\u0412', re.I)) + self.assertTrue(re.match(r'\u1c80', '\u0432', re.I)) + + # Two different characters have the same multicharacter uppercase. assert '\ufb05'.upper() == '\ufb06'.upper() == 'ST' # 'ſt', 'st' self.assertTrue(re.match(r'\ufb05', '\ufb06', re.I)) self.assertTrue(re.match(r'\ufb06', '\ufb05', re.I)) @@ -896,16 +910,31 @@ def test_ignore_case_set(self): self.assertTrue(re.match(br'[19a]', b'a', re.I)) self.assertTrue(re.match(br'[19a]', b'A', re.I)) self.assertTrue(re.match(br'[19A]', b'a', re.I)) - assert '\u212a'.lower() == 'k' # 'K' + + # Two different characters have the same lowercase. + assert 'K'.lower() == '\u212a'.lower() == 'k' # 'K' self.assertTrue(re.match(r'[19K]', '\u212a', re.I)) self.assertTrue(re.match(r'[19k]', '\u212a', re.I)) self.assertTrue(re.match(r'[19\u212a]', 'K', re.I)) self.assertTrue(re.match(r'[19\u212a]', 'k', re.I)) - assert '\u017f'.upper() == 'S' # 'ſ' + + # Two different characters have the same uppercase. + assert 's'.upper() == '\u017f'.upper() == 'S' # 'ſ' self.assertTrue(re.match(r'[19S]', '\u017f', re.I)) self.assertTrue(re.match(r'[19s]', '\u017f', re.I)) self.assertTrue(re.match(r'[19\u017f]', 'S', re.I)) self.assertTrue(re.match(r'[19\u017f]', 's', re.I)) + + # Two different characters have the same uppercase. Unicode 9.0+. + assert '\u0432'.upper() == '\u1c80'.upper() == '\u0412' # 'в', 'ᲀ', 'В' + self.assertTrue(re.match(r'[19\u0412]', '\u0432', re.I)) + self.assertTrue(re.match(r'[19\u0412]', '\u1c80', re.I)) + self.assertTrue(re.match(r'[19\u0432]', '\u0412', re.I)) + self.assertTrue(re.match(r'[19\u0432]', '\u1c80', re.I)) + self.assertTrue(re.match(r'[19\u1c80]', '\u0412', re.I)) + self.assertTrue(re.match(r'[19\u1c80]', '\u0432', re.I)) + + # Two different characters have the same multicharacter uppercase. assert '\ufb05'.upper() == '\ufb06'.upper() == 'ST' # 'ſt', 'st' self.assertTrue(re.match(r'[19\ufb05]', '\ufb06', re.I)) self.assertTrue(re.match(r'[19\ufb06]', '\ufb05', re.I)) @@ -929,16 +958,30 @@ def test_ignore_case_range(self): self.assertTrue(re.match(r'[\U00010400-\U00010427]', '\U00010428', re.I)) self.assertTrue(re.match(r'[\U00010400-\U00010427]', '\U00010400', re.I)) - assert '\u212a'.lower() == 'k' # 'K' + # Two different characters have the same lowercase. + assert 'K'.lower() == '\u212a'.lower() == 'k' # 'K' self.assertTrue(re.match(r'[J-M]', '\u212a', re.I)) self.assertTrue(re.match(r'[j-m]', '\u212a', re.I)) self.assertTrue(re.match(r'[\u2129-\u212b]', 'K', re.I)) self.assertTrue(re.match(r'[\u2129-\u212b]', 'k', re.I)) - assert '\u017f'.upper() == 'S' # 'ſ' + + # Two different characters have the same uppercase. + assert 's'.upper() == '\u017f'.upper() == 'S' # 'ſ' self.assertTrue(re.match(r'[R-T]', '\u017f', re.I)) self.assertTrue(re.match(r'[r-t]', '\u017f', re.I)) self.assertTrue(re.match(r'[\u017e-\u0180]', 'S', re.I)) self.assertTrue(re.match(r'[\u017e-\u0180]', 's', re.I)) + + # Two different characters have the same uppercase. Unicode 9.0+. + assert '\u0432'.upper() == '\u1c80'.upper() == '\u0412' # 'в', 'ᲀ', 'В' + self.assertTrue(re.match(r'[\u0411-\u0413]', '\u0432', re.I)) + self.assertTrue(re.match(r'[\u0411-\u0413]', '\u1c80', re.I)) + self.assertTrue(re.match(r'[\u0431-\u0433]', '\u0412', re.I)) + self.assertTrue(re.match(r'[\u0431-\u0433]', '\u1c80', re.I)) + self.assertTrue(re.match(r'[\u1c80-\u1c82]', '\u0412', re.I)) + self.assertTrue(re.match(r'[\u1c80-\u1c82]', '\u0432', re.I)) + + # Two different characters have the same multicharacter uppercase. assert '\ufb05'.upper() == '\ufb06'.upper() == 'ST' # 'ſt', 'st' self.assertTrue(re.match(r'[\ufb04-\ufb05]', '\ufb06', re.I)) self.assertTrue(re.match(r'[\ufb06-\ufb07]', '\ufb05', re.I)) diff --git a/Misc/NEWS.d/next/Library/2022-04-15-18-38-21.gh-issue-91575.fSyAxS.rst b/Misc/NEWS.d/next/Library/2022-04-15-18-38-21.gh-issue-91575.fSyAxS.rst new file mode 100644 index 00000000000000..ba046f2b4d61cf --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-15-18-38-21.gh-issue-91575.fSyAxS.rst @@ -0,0 +1,2 @@ +Update case-insensitive matching in the :mod:`re` module to the latest +Unicode version. From 7ade77709b5628594f6f2bedcd29f9e90337406a Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 22 Apr 2022 16:33:46 -0700 Subject: [PATCH 087/237] gh-91547: Remove "Undocumented modules" page (GH-91682) (cherry picked from commit 254aaa7981d8773658fb14795da5dec888c95f93) Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com> --- Doc/library/index.rst | 1 - Doc/library/undoc.rst | 26 ------------------- ...2-04-19-20-16-00.gh-issue-91547.LsNWER.rst | 1 + 3 files changed, 1 insertion(+), 27 deletions(-) delete mode 100644 Doc/library/undoc.rst create mode 100644 Misc/NEWS.d/next/Documentation/2022-04-19-20-16-00.gh-issue-91547.LsNWER.rst diff --git a/Doc/library/index.rst b/Doc/library/index.rst index db8f0d9bdfb8fb..7d2002b37df12c 100644 --- a/Doc/library/index.rst +++ b/Doc/library/index.rst @@ -74,5 +74,4 @@ the `Python Package Index `_. windows.rst unix.rst superseded.rst - undoc.rst security_warnings.rst diff --git a/Doc/library/undoc.rst b/Doc/library/undoc.rst deleted file mode 100644 index 2444080d6b9d90..00000000000000 --- a/Doc/library/undoc.rst +++ /dev/null @@ -1,26 +0,0 @@ -.. _undoc: - -******************** -Undocumented Modules -******************** - -Here's a quick listing of modules that are currently undocumented, but that -should be documented. Feel free to contribute documentation for them! (Send -via email to docs@python.org.) - -The idea and original contents for this chapter were taken from a posting by -Fredrik Lundh; the specific contents of this chapter have been substantially -revised. - - -Platform specific modules -========================= - -These modules are used to implement the :mod:`os.path` module, and are not -documented beyond this mention. There's little need to document these. - -:mod:`ntpath` - --- Implementation of :mod:`os.path` on Win32 and Win64 platforms. - -:mod:`posixpath` - --- Implementation of :mod:`os.path` on POSIX. diff --git a/Misc/NEWS.d/next/Documentation/2022-04-19-20-16-00.gh-issue-91547.LsNWER.rst b/Misc/NEWS.d/next/Documentation/2022-04-19-20-16-00.gh-issue-91547.LsNWER.rst new file mode 100644 index 00000000000000..95b34cb2fac1ff --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-04-19-20-16-00.gh-issue-91547.LsNWER.rst @@ -0,0 +1 @@ +Remove "Undocumented modules" page. From 0482ed7d072c9b4d55479e719d95d6e41df7b4aa Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 22 Apr 2022 17:48:13 -0700 Subject: [PATCH 088/237] gh-85864: Mark positional-only args in io docs (GH-91683) (cherry picked from commit a3f2cf3ced378db2569df4e7389ec1f79c85d55c) Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> --- Doc/library/io.rst | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Doc/library/io.rst b/Doc/library/io.rst index d5123348195bd9..b566d0c42499db 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -193,7 +193,7 @@ High-level Module Interface .. versionadded:: 3.8 -.. function:: text_encoding(encoding, stacklevel=2) +.. function:: text_encoding(encoding, stacklevel=2, /) This is a helper function for callables that use :func:`open` or :class:`TextIOWrapper` and have an ``encoding=None`` parameter. @@ -375,7 +375,7 @@ I/O Base Classes Return ``True`` if the stream can be read from. If ``False``, :meth:`read` will raise :exc:`OSError`. - .. method:: readline(size=-1) + .. method:: readline(size=-1, /) Read and return one line from the stream. If *size* is specified, at most *size* bytes will be read. @@ -384,7 +384,7 @@ I/O Base Classes the *newline* argument to :func:`open` can be used to select the line terminator(s) recognized. - .. method:: readlines(hint=-1) + .. method:: readlines(hint=-1, /) Read and return a list of lines from the stream. *hint* can be specified to control the number of lines read: no more lines will be read if the @@ -470,7 +470,7 @@ I/O Base Classes :class:`RawIOBase` provides these methods in addition to those from :class:`IOBase`: - .. method:: read(size=-1) + .. method:: read(size=-1, /) Read up to *size* bytes from the object and return them. As a convenience, if *size* is unspecified or -1, all bytes until EOF are returned. @@ -580,7 +580,7 @@ I/O Base Classes If *size* is ``-1`` (the default), an arbitrary number of bytes are returned (more than zero unless EOF is reached). - .. method:: readinto(b) + .. method:: readinto(b, /) Read bytes into a pre-allocated, writable :term:`bytes-like object` *b* and return the number of bytes read. @@ -592,7 +592,7 @@ I/O Base Classes A :exc:`BlockingIOError` is raised if the underlying raw stream is in non blocking-mode, and has no data available at the moment. - .. method:: readinto1(b) + .. method:: readinto1(b, /) Read bytes into a pre-allocated, writable :term:`bytes-like object` *b*, using at most one call to @@ -722,7 +722,7 @@ than raw I/O does. Return :class:`bytes` containing the entire contents of the buffer. - .. method:: read1([size]) + .. method:: read1([size], /) In :class:`BytesIO`, this is the same as :meth:`~BufferedIOBase.read`. @@ -800,7 +800,7 @@ than raw I/O does. Force bytes held in the buffer into the raw stream. A :exc:`BlockingIOError` should be raised if the raw stream blocks. - .. method:: write(b) + .. method:: write(b, /) Write the :term:`bytes-like object`, *b*, and return the number of bytes written. When in non-blocking mode, a @@ -823,7 +823,7 @@ than raw I/O does. are guaranteed to be implemented. -.. class:: BufferedRWPair(reader, writer, buffer_size=DEFAULT_BUFFER_SIZE) +.. class:: BufferedRWPair(reader, writer, buffer_size=DEFAULT_BUFFER_SIZE, /) A buffered binary stream providing higher-level access to two non seekable :class:`RawIOBase` raw binary streams---one readable, the other writeable. @@ -890,7 +890,7 @@ Text I/O .. versionadded:: 3.1 - .. method:: read(size=-1) + .. method:: read(size=-1, /) Read and return at most *size* characters from the stream as a single :class:`str`. If *size* is negative or ``None``, reads until EOF. From c7e6bfd1500588e5cede4590d3a721d67f915867 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 23 Apr 2022 03:16:36 -0700 Subject: [PATCH 089/237] RE: Add more tests for inline flag "x" and re.VERBOSE (GH-91854) (cherry picked from commit 6b45076bd62407103433daea8acf085a99e6cb7e) Co-authored-by: Serhiy Storchaka --- Lib/test/test_re.py | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 3d6623b596ef90..62bfc3a7aa43b5 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -1683,11 +1683,6 @@ def test_scoped_flags(self): self.assertIsNone(re.match(r'(?i:(?-i:a)b)', 'Ab')) self.assertTrue(re.match(r'(?i:(?-i:a)b)', 'aB')) - self.assertTrue(re.match(r'(?x: a) b', 'a b')) - self.assertIsNone(re.match(r'(?x: a) b', ' a b')) - self.assertTrue(re.match(r'(?-x: a) b', ' ab', re.VERBOSE)) - self.assertIsNone(re.match(r'(?-x: a) b', 'ab', re.VERBOSE)) - self.assertTrue(re.match(r'\w(?a:\W)\w', '\xe0\xe0\xe0')) self.assertTrue(re.match(r'(?a:\W(?u:\w)\W)', '\xe0\xe0\xe0')) self.assertTrue(re.match(r'\W(?u:\w)\W', '\xe0\xe0\xe0', re.ASCII)) @@ -1713,6 +1708,33 @@ def test_scoped_flags(self): self.checkPatternError(r'(?i+', 'missing -, : or )', 3) self.checkPatternError(r'(?iz', 'unknown flag', 3) + def test_ignore_spaces(self): + for space in " \t\n\r\v\f": + self.assertTrue(re.fullmatch(space + 'a', 'a', re.VERBOSE)) + for space in b" ", b"\t", b"\n", b"\r", b"\v", b"\f": + self.assertTrue(re.fullmatch(space + b'a', b'a', re.VERBOSE)) + self.assertTrue(re.fullmatch('(?x) a', 'a')) + self.assertTrue(re.fullmatch(' (?x) a', 'a', re.VERBOSE)) + self.assertTrue(re.fullmatch('(?x) (?x) a', 'a')) + self.assertTrue(re.fullmatch(' a(?x: b) c', ' ab c')) + self.assertTrue(re.fullmatch(' a(?-x: b) c', 'a bc', re.VERBOSE)) + self.assertTrue(re.fullmatch('(?x) a(?-x: b) c', 'a bc')) + self.assertTrue(re.fullmatch('(?x) a| b', 'a')) + self.assertTrue(re.fullmatch('(?x) a| b', 'b')) + + def test_comments(self): + self.assertTrue(re.fullmatch('#x\na', 'a', re.VERBOSE)) + self.assertTrue(re.fullmatch(b'#x\na', b'a', re.VERBOSE)) + self.assertTrue(re.fullmatch('(?x)#x\na', 'a')) + self.assertTrue(re.fullmatch('#x\n(?x)#y\na', 'a', re.VERBOSE)) + self.assertTrue(re.fullmatch('(?x)#x\n(?x)#y\na', 'a')) + self.assertTrue(re.fullmatch('#x\na(?x:#y\nb)#z\nc', '#x\nab#z\nc')) + self.assertTrue(re.fullmatch('#x\na(?-x:#y\nb)#z\nc', 'a#y\nbc', + re.VERBOSE)) + self.assertTrue(re.fullmatch('(?x)#x\na(?-x:#y\nb)#z\nc', 'a#y\nbc')) + self.assertTrue(re.fullmatch('(?x)#x\na|#y\nb', 'a')) + self.assertTrue(re.fullmatch('(?x)#x\na|#y\nb', 'b')) + def test_bug_6509(self): # Replacement strings of both types must parse properly. # all strings From dc31334ab1b43225b65358fa361b46c22918b400 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Sun, 24 Apr 2022 23:07:51 +0200 Subject: [PATCH 090/237] [3.10] Update Sphinx bpo role to use redirect URI. (#91890) * Update Sphinx bpo role to use redirect URI. (GH-32342) * [3.10] Update Sphinx bpo role to use redirect URI. (GH-32342). (cherry picked from commit 08cfe079503ffd19d8b7ab324f0fdb1c6b150ca8) Co-authored-by: Ezio Melotti * Fix whitespace. --- Doc/tools/extensions/pyspecific.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index 7f505a1ede89a4..cce364c0e6245d 100644 --- a/Doc/tools/extensions/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -43,7 +43,7 @@ import suspicious -ISSUE_URI = 'https://bugs.python.org/issue%s' +ISSUE_URI = 'https://bugs.python.org/issue?@action=redirect&bpo=%s' SOURCE_URI = 'https://github.com/python/cpython/tree/3.10/%s' # monkey-patch reST parser to disable alphabetic and roman enumerated lists From 971343eb569a3418aa9a0bad9b638cccf1470ef8 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 25 Apr 2022 08:03:47 -0700 Subject: [PATCH 091/237] gh-91904: Fix setting envvar PYTHONREGRTEST_UNICODE_GUARD (GH-91905) It always failed on non-UTF-8 locale and prevented running regrtests. (cherry picked from commit 54d068adfbf2b822bcbf90dac9b3f6684cec0f99) Co-authored-by: Serhiy Storchaka --- Lib/test/libregrtest/setup.py | 9 +++++---- Lib/test/test_regrtest.py | 2 +- .../Tests/2022-04-25-11-16-36.gh-issue-91904.13Uvrz.rst | 2 ++ 3 files changed, 8 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2022-04-25-11-16-36.gh-issue-91904.13Uvrz.rst diff --git a/Lib/test/libregrtest/setup.py b/Lib/test/libregrtest/setup.py index b79175944d2bdf..0bfd644bb3179d 100644 --- a/Lib/test/libregrtest/setup.py +++ b/Lib/test/libregrtest/setup.py @@ -5,6 +5,7 @@ import sys import unittest from test import support +from test.support.os_helper import TESTFN_UNDECODABLE, FS_NONASCII try: import gc except ImportError: @@ -105,10 +106,10 @@ def _test_audit_hook(name, args): # Ensure there's a non-ASCII character in env vars at all times to force # tests consider this case. See BPO-44647 for details. - os.environ.setdefault( - UNICODE_GUARD_ENV, - "\N{SMILING FACE WITH SUNGLASSES}", - ) + if TESTFN_UNDECODABLE and os.supports_bytes_environ: + os.environb.setdefault(UNICODE_GUARD_ENV.encode(), TESTFN_UNDECODABLE) + elif FS_NONASCII: + os.environ.setdefault(UNICODE_GUARD_ENV, FS_NONASCII) def replace_stdout(): diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py index 3780feeda30e1b..62e6c28280e61f 100644 --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -1303,7 +1303,7 @@ def test_threading_excepthook(self): def test_unicode_guard_env(self): guard = os.environ.get(setup.UNICODE_GUARD_ENV) self.assertIsNotNone(guard, f"{setup.UNICODE_GUARD_ENV} not set") - if guard != "\N{SMILING FACE WITH SUNGLASSES}": + if guard.isascii(): # Skip to signify that the env var value was changed by the user; # possibly to something ASCII to work around Unicode issues. self.skipTest("Modified guard") diff --git a/Misc/NEWS.d/next/Tests/2022-04-25-11-16-36.gh-issue-91904.13Uvrz.rst b/Misc/NEWS.d/next/Tests/2022-04-25-11-16-36.gh-issue-91904.13Uvrz.rst new file mode 100644 index 00000000000000..31ddfc312866b8 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-04-25-11-16-36.gh-issue-91904.13Uvrz.rst @@ -0,0 +1,2 @@ +Fix initialization of :envvar:`PYTHONREGRTEST_UNICODE_GUARD` which prevented +running regression tests on non-UTF-8 locale. From 4120bbae4930cfd74649118e0bcc2fb5dd32b1fa Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Tue, 26 Apr 2022 02:51:28 +0200 Subject: [PATCH 092/237] [3.10] gh-91888: add a :gh: role to the documentation (GH-91889) (#91934) * gh-91888: Add a :gh: role to the documentation (GH-91889). * [3.10] gh-91888: add a `:gh:` role to the documentation (GH-91889) * Add a new :gh:`...` role for GitHub issues. * Fix a GitHub id to use the :gh: role. * Add Misc/NEWS entry. * Refactoring and rephrasing. Co-authored-by: Hugo van Kemenade . (cherry picked from commit f7641a2ffec243e5f600028a84debe9028a9ee44) Co-authored-by: Ezio Melotti --- Doc/tools/extensions/pyspecific.py | 24 +++++++++++++++++++ ...2-04-24-22-09-31.gh-issue-91888.kTjJLx.rst | 1 + 2 files changed, 25 insertions(+) create mode 100644 Misc/NEWS.d/next/Documentation/2022-04-24-22-09-31.gh-issue-91888.kTjJLx.rst diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index cce364c0e6245d..cbb7638627ef14 100644 --- a/Doc/tools/extensions/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -44,6 +44,7 @@ ISSUE_URI = 'https://bugs.python.org/issue?@action=redirect&bpo=%s' +GH_ISSUE_URI = 'https://github.com/python/cpython/issues/%s' SOURCE_URI = 'https://github.com/python/cpython/tree/3.10/%s' # monkey-patch reST parser to disable alphabetic and roman enumerated lists @@ -58,11 +59,33 @@ def issue_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): issue = utils.unescape(text) + # sanity check: there are no bpo issues within these two values + if 47261 < int(issue) < 400000: + msg = inliner.reporter.error(f'The BPO ID {text!r} seems too high -- ' + 'use :gh:`...` for GitHub IDs', line=lineno) + prb = inliner.problematic(rawtext, rawtext, msg) + return [prb], [msg] text = 'bpo-' + issue refnode = nodes.reference(text, text, refuri=ISSUE_URI % issue) return [refnode], [] +# Support for marking up and linking to GitHub issues + +def gh_issue_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): + issue = utils.unescape(text) + # sanity check: all GitHub issues have ID >= 32426 + # even though some of them are also valid BPO IDs + if int(issue) < 32426: + msg = inliner.reporter.error(f'The GitHub ID {text!r} seems too low -- ' + 'use :issue:`...` for BPO IDs', line=lineno) + prb = inliner.problematic(rawtext, rawtext, msg) + return [prb], [msg] + text = 'gh-' + issue + refnode = nodes.reference(text, text, refuri=GH_ISSUE_URI % issue) + return [refnode], [] + + # Support for linking to Python source files easily def source_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): @@ -615,6 +638,7 @@ def process_audit_events(app, doctree, fromdocname): def setup(app): app.add_role('issue', issue_role) + app.add_role('gh', gh_issue_role) app.add_role('source', source_role) app.add_directive('impl-detail', ImplementationDetail) app.add_directive('availability', Availability) diff --git a/Misc/NEWS.d/next/Documentation/2022-04-24-22-09-31.gh-issue-91888.kTjJLx.rst b/Misc/NEWS.d/next/Documentation/2022-04-24-22-09-31.gh-issue-91888.kTjJLx.rst new file mode 100644 index 00000000000000..9194be9dbf92df --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-04-24-22-09-31.gh-issue-91888.kTjJLx.rst @@ -0,0 +1 @@ +Add a new `gh` role to the documentation to link to GitHub issues. From 79712c9d2ec7a338b87d1a8b31a8404191e83823 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 25 Apr 2022 22:26:47 -0700 Subject: [PATCH 093/237] gh-91916: Fix test_runpy on non-UTF-8 locale (GH-91920) If use a non-builtin codec, partially implemented in Python (e.g. ISO-8859-15), a new RecursionError (with empty error message) can be raised while handle a RecursionError. Testing for error message was needed to distinguish a recursion error from arbitrary RuntimeError. After introducing RecursionError, it became unnecessary. (cherry picked from commit a568585069174cec35ce26cdf4d4862c634d9f6d) Co-authored-by: Serhiy Storchaka --- Lib/test/test_runpy.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py index 2954dfedc7e428..e6d36825f15a11 100644 --- a/Lib/test/test_runpy.py +++ b/Lib/test/test_runpy.py @@ -740,8 +740,7 @@ def test_main_recursion_error(self): "runpy.run_path(%r)\n") % dummy_dir script_name = self._make_test_script(script_dir, mod_name, source) zip_name, fname = make_zip_script(script_dir, 'test_zip', script_name) - msg = "recursion depth exceeded" - self.assertRaisesRegex(RecursionError, msg, run_path, zip_name) + self.assertRaises(RecursionError, run_path, zip_name) def test_encoding(self): with temp_dir() as script_dir: From 3e219d312321a1dbb3a475607dfcaaa5925fed79 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 25 Apr 2022 22:57:57 -0700 Subject: [PATCH 094/237] gh-91914: Fix test_curses on non-UTF-8 locale (GH-91919) (cherry picked from commit f41c16bf512778fca4bfabca887c4c303cc21896) Co-authored-by: Serhiy Storchaka --- Lib/test/test_curses.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py index d3c152c42cf62f..b550f4af555ce4 100644 --- a/Lib/test/test_curses.py +++ b/Lib/test/test_curses.py @@ -268,7 +268,12 @@ def test_output_character(self): stdscr.echochar(b'A') stdscr.echochar(65) with self.assertRaises((UnicodeEncodeError, OverflowError)): - stdscr.echochar('\u20ac') + # Unicode is not fully supported yet, but at least it does + # not crash. + # It is supposed to fail because either the character is + # not encodable with the current encoding, or it is encoded to + # a multibyte sequence. + stdscr.echochar('\u0114') stdscr.echochar('A', curses.A_BOLD) self.assertIs(stdscr.is_wintouched(), False) From dbe666d39880352360cb07787d47237448196bf4 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 26 Apr 2022 10:50:22 +0300 Subject: [PATCH 095/237] [3.10] gh-91915: Fix test_netrc on non-UTF-8 locale (GH-91918). (GH-91946) (cherry picked from commit 36306cf7862097318a3fef74224075cc4cf37229) Co-authored-by: Serhiy Storchaka --- Lib/test/test_netrc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_netrc.py b/Lib/test/test_netrc.py index 90ef5cd363b3fb..8c76bc701e4944 100644 --- a/Lib/test/test_netrc.py +++ b/Lib/test/test_netrc.py @@ -11,7 +11,7 @@ def make_nrc(self, test_data): if sys.platform != 'cygwin': mode += 't' temp_fd, temp_filename = tempfile.mkstemp() - with os.fdopen(temp_fd, mode=mode) as fp: + with os.fdopen(temp_fd, mode=mode, encoding="utf-8") as fp: fp.write(test_data) self.addCleanup(os.unlink, temp_filename) return netrc.netrc(temp_filename) From 280749a8fdfa9b42e249b7e09d2b44607fff228d Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 27 Apr 2022 00:08:05 -0700 Subject: [PATCH 096/237] Fix missing `f` prefix on f-strings (GH-91910) (cherry picked from commit f882d33778ee2625ab32d90e28edb6878fb8af93) Co-authored-by: Alexander Shadchin --- Lib/asyncio/base_events.py | 2 +- Lib/multiprocessing/util.py | 2 +- .../next/Library/2022-04-25-14-18-01.gh-issue-91910.kY-JR0.rst | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-04-25-14-18-01.gh-issue-91910.kY-JR0.rst diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 952da11064fefa..ea10399b941310 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -884,7 +884,7 @@ async def _sock_sendfile_native(self, sock, file, offset, count): # non-mmap files even if sendfile is supported by OS raise exceptions.SendfileNotAvailableError( f"syscall sendfile is not available for socket {sock!r} " - "and file {file!r} combination") + f"and file {file!r} combination") async def _sock_sendfile_fallback(self, sock, file, offset, count): if offset: diff --git a/Lib/multiprocessing/util.py b/Lib/multiprocessing/util.py index a4683339820f5f..9e07a4e93e597e 100644 --- a/Lib/multiprocessing/util.py +++ b/Lib/multiprocessing/util.py @@ -120,7 +120,7 @@ def is_abstract_socket_namespace(address): return address[0] == 0 elif isinstance(address, str): return address[0] == "\0" - raise TypeError('address type of {address!r} unrecognized') + raise TypeError(f'address type of {address!r} unrecognized') abstract_sockets_supported = _platform_supports_abstract_sockets() diff --git a/Misc/NEWS.d/next/Library/2022-04-25-14-18-01.gh-issue-91910.kY-JR0.rst b/Misc/NEWS.d/next/Library/2022-04-25-14-18-01.gh-issue-91910.kY-JR0.rst new file mode 100644 index 00000000000000..f41f357ddfcc3a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-25-14-18-01.gh-issue-91910.kY-JR0.rst @@ -0,0 +1 @@ +Add missing f prefix to f-strings in error messages from the :mod:`multiprocessing` and :mod:`asyncio` modules. From a36d97e3f1daeb431e1c5bc8ab83daca93b747b0 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 27 Apr 2022 11:39:51 +0200 Subject: [PATCH 097/237] gh-68966: Document mailcap deprecation in Python 3.11 (#91971) (cherry picked from commit 80de0273c0caf8bae19787bb00255eb3fb2a2d0c) --- Doc/library/mailcap.rst | 5 +++++ Doc/library/netdata.rst | 1 - Doc/library/superseded.rst | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Doc/library/mailcap.rst b/Doc/library/mailcap.rst index 7749b7dd45ef44..416b181f45a772 100644 --- a/Doc/library/mailcap.rst +++ b/Doc/library/mailcap.rst @@ -3,9 +3,14 @@ .. module:: mailcap :synopsis: Mailcap file handling. + :deprecated: **Source code:** :source:`Lib/mailcap.py` +.. deprecated:: 3.11 + The :mod:`mailcap` module is deprecated. See :pep:`594` for the rationale + and the :mod:`mimetypes` module for an alternative. + -------------- Mailcap files are used to configure how MIME-aware applications such as mail diff --git a/Doc/library/netdata.rst b/Doc/library/netdata.rst index 0e6ebd3b02ddde..1cf717332731ca 100644 --- a/Doc/library/netdata.rst +++ b/Doc/library/netdata.rst @@ -13,7 +13,6 @@ on the internet. email.rst json.rst - mailcap.rst mailbox.rst mimetypes.rst base64.rst diff --git a/Doc/library/superseded.rst b/Doc/library/superseded.rst index e3f9b0d37fe10b..b38f16691f6ea9 100644 --- a/Doc/library/superseded.rst +++ b/Doc/library/superseded.rst @@ -20,9 +20,10 @@ backwards compatibility. They have been superseded by other modules. crypt.rst imghdr.rst imp.rst + mailcap.rst msilib.rst - nntplib.rst nis.rst + nntplib.rst optparse.rst ossaudiodev.rst pipes.rst From 777d478d12573e126b7c0b29be493aa1048cdb7e Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 27 Apr 2022 09:50:25 -0700 Subject: [PATCH 098/237] gh-91810: Expand ElementTree.write() tests to use non-ASCII data (GH-91989) (cherry picked from commit f60b4c3d74f241775f80affe60dcba6448634fe3) Co-authored-by: Serhiy Storchaka --- Lib/test/test_xml_etree.py | 97 +++++++++++++++++++++++++++++++------- 1 file changed, 80 insertions(+), 17 deletions(-) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index 5a34d848b3944c..cb6d1697f1da88 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -130,6 +130,9 @@ def newtest(*args, **kwargs): return newtest return decorator +def convlinesep(data): + return data.replace(b'\n', os.linesep.encode()) + class ModuleTest(unittest.TestCase): def test_sanity(self): @@ -3713,32 +3716,92 @@ def test_encoding(self): def test_write_to_filename(self): self.addCleanup(os_helper.unlink, TESTFN) - tree = ET.ElementTree(ET.XML('''''')) + tree = ET.ElementTree(ET.XML('''\xf8''')) tree.write(TESTFN) with open(TESTFN, 'rb') as f: - self.assertEqual(f.read(), b'''''') + self.assertEqual(f.read(), b'''ø''') + + def test_write_to_filename_with_encoding(self): + self.addCleanup(os_helper.unlink, TESTFN) + tree = ET.ElementTree(ET.XML('''\xf8''')) + tree.write(TESTFN, encoding='utf-8') + with open(TESTFN, 'rb') as f: + self.assertEqual(f.read(), b'''\xc3\xb8''') + + tree.write(TESTFN, encoding='ISO-8859-1') + with open(TESTFN, 'rb') as f: + self.assertEqual(f.read(), convlinesep( + b'''\n''' + b'''\xf8''')) + + def test_write_to_filename_as_unicode(self): + self.addCleanup(os_helper.unlink, TESTFN) + with open(TESTFN, 'w') as f: + encoding = f.encoding + os_helper.unlink(TESTFN) + + try: + '\xf8'.encode(encoding) + except UnicodeEncodeError: + self.skipTest(f'default file encoding {encoding} not supported') + + tree = ET.ElementTree(ET.XML('''\xf8''')) + tree.write(TESTFN, encoding='unicode') + with open(TESTFN, 'rb') as f: + data = f.read() + expected = "\xf8".encode(encoding, 'xmlcharrefreplace') + self.assertEqual(data, expected) def test_write_to_text_file(self): self.addCleanup(os_helper.unlink, TESTFN) - tree = ET.ElementTree(ET.XML('''''')) + tree = ET.ElementTree(ET.XML('''\xf8''')) with open(TESTFN, 'w', encoding='utf-8') as f: tree.write(f, encoding='unicode') self.assertFalse(f.closed) with open(TESTFN, 'rb') as f: - self.assertEqual(f.read(), b'''''') + self.assertEqual(f.read(), b'''\xc3\xb8''') + + with open(TESTFN, 'w', encoding='ascii', errors='xmlcharrefreplace') as f: + tree.write(f, encoding='unicode') + self.assertFalse(f.closed) + with open(TESTFN, 'rb') as f: + self.assertEqual(f.read(), b'''ø''') + + with open(TESTFN, 'w', encoding='ISO-8859-1') as f: + tree.write(f, encoding='unicode') + self.assertFalse(f.closed) + with open(TESTFN, 'rb') as f: + self.assertEqual(f.read(), b'''\xf8''') def test_write_to_binary_file(self): self.addCleanup(os_helper.unlink, TESTFN) - tree = ET.ElementTree(ET.XML('''''')) + tree = ET.ElementTree(ET.XML('''\xf8''')) with open(TESTFN, 'wb') as f: tree.write(f) self.assertFalse(f.closed) with open(TESTFN, 'rb') as f: - self.assertEqual(f.read(), b'''''') + self.assertEqual(f.read(), b'''ø''') + + def test_write_to_binary_file_with_encoding(self): + self.addCleanup(os_helper.unlink, TESTFN) + tree = ET.ElementTree(ET.XML('''\xf8''')) + with open(TESTFN, 'wb') as f: + tree.write(f, encoding='utf-8') + self.assertFalse(f.closed) + with open(TESTFN, 'rb') as f: + self.assertEqual(f.read(), b'''\xc3\xb8''') + + with open(TESTFN, 'wb') as f: + tree.write(f, encoding='ISO-8859-1') + self.assertFalse(f.closed) + with open(TESTFN, 'rb') as f: + self.assertEqual(f.read(), + b'''\n''' + b'''\xf8''') def test_write_to_binary_file_with_bom(self): self.addCleanup(os_helper.unlink, TESTFN) - tree = ET.ElementTree(ET.XML('''''')) + tree = ET.ElementTree(ET.XML('''\xf8''')) # test BOM writing to buffered file with open(TESTFN, 'wb') as f: tree.write(f, encoding='utf-16') @@ -3746,7 +3809,7 @@ def test_write_to_binary_file_with_bom(self): with open(TESTFN, 'rb') as f: self.assertEqual(f.read(), '''\n''' - ''''''.encode("utf-16")) + '''\xf8'''.encode("utf-16")) # test BOM writing to non-buffered file with open(TESTFN, 'wb', buffering=0) as f: tree.write(f, encoding='utf-16') @@ -3754,7 +3817,7 @@ def test_write_to_binary_file_with_bom(self): with open(TESTFN, 'rb') as f: self.assertEqual(f.read(), '''\n''' - ''''''.encode("utf-16")) + '''\xf8'''.encode("utf-16")) def test_read_from_stringio(self): tree = ET.ElementTree() @@ -3763,10 +3826,10 @@ def test_read_from_stringio(self): self.assertEqual(tree.getroot().tag, 'site') def test_write_to_stringio(self): - tree = ET.ElementTree(ET.XML('''''')) + tree = ET.ElementTree(ET.XML('''\xf8''')) stream = io.StringIO() tree.write(stream, encoding='unicode') - self.assertEqual(stream.getvalue(), '''''') + self.assertEqual(stream.getvalue(), '''\xf8''') def test_read_from_bytesio(self): tree = ET.ElementTree() @@ -3775,10 +3838,10 @@ def test_read_from_bytesio(self): self.assertEqual(tree.getroot().tag, 'site') def test_write_to_bytesio(self): - tree = ET.ElementTree(ET.XML('''''')) + tree = ET.ElementTree(ET.XML('''\xf8''')) raw = io.BytesIO() tree.write(raw) - self.assertEqual(raw.getvalue(), b'''''') + self.assertEqual(raw.getvalue(), b'''ø''') class dummy: pass @@ -3792,12 +3855,12 @@ def test_read_from_user_text_reader(self): self.assertEqual(tree.getroot().tag, 'site') def test_write_to_user_text_writer(self): - tree = ET.ElementTree(ET.XML('''''')) + tree = ET.ElementTree(ET.XML('''\xf8''')) stream = io.StringIO() writer = self.dummy() writer.write = stream.write tree.write(writer, encoding='unicode') - self.assertEqual(stream.getvalue(), '''''') + self.assertEqual(stream.getvalue(), '''\xf8''') def test_read_from_user_binary_reader(self): raw = io.BytesIO(b'''''') @@ -3809,12 +3872,12 @@ def test_read_from_user_binary_reader(self): tree = ET.ElementTree() def test_write_to_user_binary_writer(self): - tree = ET.ElementTree(ET.XML('''''')) + tree = ET.ElementTree(ET.XML('''\xf8''')) raw = io.BytesIO() writer = self.dummy() writer.write = raw.write tree.write(writer) - self.assertEqual(raw.getvalue(), b'''''') + self.assertEqual(raw.getvalue(), b'''ø''') def test_write_to_user_binary_writer_with_bom(self): tree = ET.ElementTree(ET.XML('''''')) From 86e4bdaf493d3d5e0ded31d170eafd2a15a57f8f Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 27 Apr 2022 15:18:06 -0700 Subject: [PATCH 099/237] gh-84459: Make wording more specific for Path.replace (GH-91853) GH-84459 (cherry picked from commit 161dff7e10eeb7eaf6d418b91e993aaf84770a5c) Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> --- Doc/library/os.rst | 2 +- Doc/library/pathlib.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/os.rst b/Doc/library/os.rst index dbd3c968dd35ac..b81574b7eaa469 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -2338,7 +2338,7 @@ features: .. function:: replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None) - Rename the file or directory *src* to *dst*. If *dst* is a directory, + Rename the file or directory *src* to *dst*. If *dst* is a non-empty directory, :exc:`OSError` will be raised. If *dst* exists and is a file, it will be replaced silently if the user has permission. The operation may fail if *src* and *dst* are on different filesystems. If successful, diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index fedea34bcd0c4b..f036d8119243a6 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -1042,7 +1042,7 @@ call fails (for example because the path doesn't exist). Rename this file or directory to the given *target*, and return a new Path instance pointing to *target*. If *target* points to an existing file or - directory, it will be unconditionally replaced. + empty directory, it will be unconditionally replaced. The target path may be absolute or relative. Relative paths are interpreted relative to the current working directory, *not* the directory of the Path From e2514cb77fcbdb5c733ae2532802a78e7cb08e79 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 27 Apr 2022 15:19:43 -0700 Subject: [PATCH 100/237] Correct method name typo (GH-91970) (cherry picked from commit c6b84a727c9299f24edbab4105ce47e9f2bae199) Co-authored-by: Simon de Vlieger --- Lib/difflib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/difflib.py b/Lib/difflib.py index afd8a0c7c5b61e..ba0b256969ebff 100644 --- a/Lib/difflib.py +++ b/Lib/difflib.py @@ -837,7 +837,7 @@ def compare(self, a, b): Each sequence must contain individual single-line strings ending with newlines. Such sequences can be obtained from the `readlines()` method of file-like objects. The delta generated also consists of newline- - terminated strings, ready to be printed as-is via the writeline() + terminated strings, ready to be printed as-is via the writelines() method of a file-like object. Example: From e25799d27d049237849c471b25db3b128b1bfa08 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 27 Apr 2022 15:26:42 -0700 Subject: [PATCH 101/237] Add note that headers added via urllib.request.add_header are added to redirected requests (GH-30708) (#92004) (cherry picked from commit f348154c8f8a9c254503306c59d6779d4d09b3a9) Co-authored-by: Ashwin Ramaswami Co-authored-by: Ashwin Ramaswami --- Doc/library/urllib.request.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index 9573683dd05944..39d1a277aa6c75 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -547,7 +547,8 @@ request. name, and later calls will overwrite previous calls in case the *key* collides. Currently, this is no loss of HTTP functionality, since all headers which have meaning when used more than once have a (header-specific) way of gaining the - same functionality using only one header. + same functionality using only one header. Note that headers added using + this method are also added to redirected requests. .. method:: Request.add_unredirected_header(key, header) From 11652ceccf1dbf9dd332ad52ac9bd41b4adff274 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 28 Apr 2022 08:27:17 -0700 Subject: [PATCH 102/237] gh-91832: Add 'required' attr to argparse.Action repr (GH-91841) GH- Adding 'required' to names in Lib.argparse.Action gh-91832: Added 'required' to the list `names` in `Lib.argparse.Action`. Changed constant strings that test the Action object. Automerge-Triggered-By: GH:merwok (cherry picked from commit 4ed3900041c688a02dca1eb3323083d720dd0d93) Co-authored-by: Abhigyan Bose --- Lib/argparse.py | 1 + Lib/test/test_argparse.py | 6 ++++-- .../Library/2022-04-23-03-24-00.gh-issue-91832.TyLi65.rst | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-04-23-03-24-00.gh-issue-91832.TyLi65.rst diff --git a/Lib/argparse.py b/Lib/argparse.py index 2c0dd853a5bdd3..9be18488abe5ba 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -848,6 +848,7 @@ def _get_kwargs(self): 'default', 'type', 'choices', + 'required', 'help', 'metavar', ] diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index d4426bab5e09a5..0b237ab5b93023 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -4873,12 +4873,13 @@ def test_optional(self): nargs='+', default=42, choices=[1, 2, 3], + required=False, help='HELP', metavar='METAVAR') string = ( "Action(option_strings=['--foo', '-a', '-b'], dest='b', " "nargs='+', const=None, default=42, type='int', " - "choices=[1, 2, 3], help='HELP', metavar='METAVAR')") + "choices=[1, 2, 3], required=False, help='HELP', metavar='METAVAR')") self.assertStringEqual(option, string) def test_argument(self): @@ -4889,12 +4890,13 @@ def test_argument(self): nargs='?', default=2.5, choices=[0.5, 1.5, 2.5], + required=True, help='H HH H', metavar='MV MV MV') string = ( "Action(option_strings=[], dest='x', nargs='?', " "const=None, default=2.5, type=%r, choices=[0.5, 1.5, 2.5], " - "help='H HH H', metavar='MV MV MV')" % float) + "required=True, help='H HH H', metavar='MV MV MV')" % float) self.assertStringEqual(argument, string) def test_namespace(self): diff --git a/Misc/NEWS.d/next/Library/2022-04-23-03-24-00.gh-issue-91832.TyLi65.rst b/Misc/NEWS.d/next/Library/2022-04-23-03-24-00.gh-issue-91832.TyLi65.rst new file mode 100644 index 00000000000000..0ebf7735465586 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-23-03-24-00.gh-issue-91832.TyLi65.rst @@ -0,0 +1 @@ +Add ``required`` attribute to :class:`argparse.Action` repr output. From 7bd4411b90e9f4b376754be23b5f6b86bf4e3c5f Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 29 Apr 2022 11:45:43 -0700 Subject: [PATCH 103/237] bpo-26792: Improve docstrings of runpy module run_functions (GH-30729) Co-authored-by: Jelle Zijlstra Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> (cherry picked from commit 117836f123a1c65d9ba50401822b883f11f0a347) Co-authored-by: Humbled Drugman --- Lib/runpy.py | 36 ++++++++++++++----- .../2022-01-23-20-44-53.bpo-26792.dQ1v1W.rst | 2 ++ 2 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2022-01-23-20-44-53.bpo-26792.dQ1v1W.rst diff --git a/Lib/runpy.py b/Lib/runpy.py index caba1214262380..c7d3d8caad1611 100644 --- a/Lib/runpy.py +++ b/Lib/runpy.py @@ -198,9 +198,24 @@ def _run_module_as_main(mod_name, alter_argv=True): def run_module(mod_name, init_globals=None, run_name=None, alter_sys=False): - """Execute a module's code without importing it + """Execute a module's code without importing it. - Returns the resulting top level namespace dictionary + mod_name -- an absolute module name or package name. + + Optional arguments: + init_globals -- dictionary used to pre-populate the module’s + globals dictionary before the code is executed. + + run_name -- if not None, this will be used for setting __name__; + otherwise, __name__ will be set to mod_name + '__main__' if the + named module is a package and to just mod_name otherwise. + + alter_sys -- if True, sys.argv[0] is updated with the value of + __file__ and sys.modules[__name__] is updated with a temporary + module object for the module being executed. Both are + restored to their original values before the function returns. + + Returns the resulting module globals dictionary. """ mod_name, mod_spec, code = _get_module_details(mod_name) if run_name is None: @@ -243,14 +258,19 @@ def _get_code_from_file(run_name, fname): return code, fname def run_path(path_name, init_globals=None, run_name=None): - """Execute code located at the specified filesystem location + """Execute code located at the specified filesystem location. + + path_name -- filesystem location of a Python script, zipfile, + or directory containing a top level __main__.py script. + + Optional arguments: + init_globals -- dictionary used to pre-populate the module’s + globals dictionary before the code is executed. - Returns the resulting top level namespace dictionary + run_name -- if not None, this will be used to set __name__; + otherwise, '' will be used for __name__. - The file path may refer directly to a Python script (i.e. - one that could be directly executed with execfile) or else - it may refer to a zipfile or directory containing a top - level __main__.py script. + Returns the resulting module globals dictionary. """ if run_name is None: run_name = "" diff --git a/Misc/NEWS.d/next/Documentation/2022-01-23-20-44-53.bpo-26792.dQ1v1W.rst b/Misc/NEWS.d/next/Documentation/2022-01-23-20-44-53.bpo-26792.dQ1v1W.rst new file mode 100644 index 00000000000000..64a39564476019 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-01-23-20-44-53.bpo-26792.dQ1v1W.rst @@ -0,0 +1,2 @@ +Improve the docstrings of :func:`runpy.run_module` and :func:`runpy.run_path`. +Original patch by Andrew Brezovsky. From 7149b21c2e990d1b641bc71c6ffc3cb153d0500d Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 29 Apr 2022 15:25:31 -0700 Subject: [PATCH 104/237] sorting howto: Add clarification on < using __lt__ (GH-92010) (cherry picked from commit 53ca774497fde7c5fcf3a84813ea42f95f75c639) Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> --- Doc/howto/sorting.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Doc/howto/sorting.rst b/Doc/howto/sorting.rst index 37328c82dff270..32b47711f85705 100644 --- a/Doc/howto/sorting.rst +++ b/Doc/howto/sorting.rst @@ -325,7 +325,7 @@ Odd and Ends >>> standard_way [('red', 1), ('red', 2), ('blue', 1), ('blue', 2)] -* The sort routines are guaranteed to use :meth:`__lt__` when making comparisons +* The sort routines use ``<`` when making comparisons between two objects. So, it is easy to add a standard sort order to a class by defining an :meth:`__lt__` method: @@ -335,6 +335,9 @@ Odd and Ends >>> sorted(student_objects) [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] + However, note that ``<`` can fall back to using :meth:`__gt__` if + :meth:`__lt__` is not implemented (see :func:`object.__lt__`). + * Key functions need not depend directly on the objects being sorted. A key function can also access external resources. For instance, if the student grades are stored in a dictionary, they can be used to sort a separate list of student From 19a079690c29cd6a9f3fc3cb6aeb9f5a11c491e3 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 30 Apr 2022 05:31:28 -0700 Subject: [PATCH 105/237] bpo-43323: Fix UnicodeEncodeError in the email module (GH-32137) It was raised if the charset itself contains characters not encodable in UTF-8 (in particular \udcxx characters representing non-decodable bytes in the source). (cherry picked from commit e91dee87edcf6dee5dd78053004d76e5f05456d4) Co-authored-by: Serhiy Storchaka --- Lib/email/_encoded_words.py | 10 +++++----- Lib/email/_header_value_parser.py | 2 +- Lib/test/test_email/test__encoded_words.py | 7 +++++++ Lib/test/test_email/test_email.py | 9 +++++++++ Lib/test/test_email/test_headerregistry.py | 12 ++++++++++++ .../Library/2022-03-27-12-40-16.bpo-43323.9mFPuI.rst | 2 ++ 6 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-03-27-12-40-16.bpo-43323.9mFPuI.rst diff --git a/Lib/email/_encoded_words.py b/Lib/email/_encoded_words.py index 295ae7eb21237c..6795a606de037e 100644 --- a/Lib/email/_encoded_words.py +++ b/Lib/email/_encoded_words.py @@ -179,15 +179,15 @@ def decode(ew): # Turn the CTE decoded bytes into unicode. try: string = bstring.decode(charset) - except UnicodeError: + except UnicodeDecodeError: defects.append(errors.UndecodableBytesDefect("Encoded word " - "contains bytes not decodable using {} charset".format(charset))) + f"contains bytes not decodable using {charset!r} charset")) string = bstring.decode(charset, 'surrogateescape') - except LookupError: + except (LookupError, UnicodeEncodeError): string = bstring.decode('ascii', 'surrogateescape') if charset.lower() != 'unknown-8bit': - defects.append(errors.CharsetError("Unknown charset {} " - "in encoded word; decoded as unknown bytes".format(charset))) + defects.append(errors.CharsetError(f"Unknown charset {charset!r} " + f"in encoded word; decoded as unknown bytes")) return string, charset, lang, defects diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py index 51d355fbb0abc5..8a8fb8bc42a954 100644 --- a/Lib/email/_header_value_parser.py +++ b/Lib/email/_header_value_parser.py @@ -781,7 +781,7 @@ def params(self): else: try: value = value.decode(charset, 'surrogateescape') - except LookupError: + except (LookupError, UnicodeEncodeError): # XXX: there should really be a custom defect for # unknown character set to make it easy to find, # because otherwise unknown charset is a silent diff --git a/Lib/test/test_email/test__encoded_words.py b/Lib/test/test_email/test__encoded_words.py index 0b8b1de3359aa6..1713962f94caef 100644 --- a/Lib/test/test_email/test__encoded_words.py +++ b/Lib/test/test_email/test__encoded_words.py @@ -130,6 +130,13 @@ def test_unknown_charset(self): # XXX Should this be a new Defect instead? defects = [errors.CharsetError]) + def test_invalid_character_in_charset(self): + self._test('=?utf-8\udce2\udc80\udc9d?q?foo=ACbar?=', + b'foo\xacbar'.decode('ascii', 'surrogateescape'), + charset = 'utf-8\udce2\udc80\udc9d', + # XXX Should this be a new Defect instead? + defects = [errors.CharsetError]) + def test_q_nonascii(self): self._test('=?utf-8?q?=C3=89ric?=', 'Éric', diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py index a3ccbbbabfb328..af0ea03fedf0cb 100644 --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -5323,6 +5323,15 @@ def test_rfc2231_unknown_encoding(self): Content-Transfer-Encoding: 8bit Content-Disposition: inline; filename*=X-UNKNOWN''myfile.txt +""" + msg = email.message_from_string(m) + self.assertEqual(msg.get_filename(), 'myfile.txt') + + def test_rfc2231_bad_character_in_encoding(self): + m = """\ +Content-Transfer-Encoding: 8bit +Content-Disposition: inline; filename*=utf-8\udce2\udc80\udc9d''myfile.txt + """ msg = email.message_from_string(m) self.assertEqual(msg.get_filename(), 'myfile.txt') diff --git a/Lib/test/test_email/test_headerregistry.py b/Lib/test/test_email/test_headerregistry.py index 59fcd932e0ec4a..25347ef13c2147 100644 --- a/Lib/test/test_email/test_headerregistry.py +++ b/Lib/test/test_email/test_headerregistry.py @@ -714,6 +714,18 @@ def content_type_as_value(self, " charset*=unknown-8bit''utf-8%E2%80%9D\n", ), + 'rfc2231_nonascii_in_charset_of_charset_parameter_value': ( + "text/plain; charset*=utf-8”''utf-8%E2%80%9D", + 'text/plain', + 'text', + 'plain', + {'charset': 'utf-8”'}, + [], + 'text/plain; charset="utf-8”"', + "Content-Type: text/plain;" + " charset*=utf-8''utf-8%E2%80%9D\n", + ), + 'rfc2231_encoded_then_unencoded_segments': ( ('application/x-foo;' '\tname*0*="us-ascii\'en-us\'My";' diff --git a/Misc/NEWS.d/next/Library/2022-03-27-12-40-16.bpo-43323.9mFPuI.rst b/Misc/NEWS.d/next/Library/2022-03-27-12-40-16.bpo-43323.9mFPuI.rst new file mode 100644 index 00000000000000..98d73101d3ee57 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-27-12-40-16.bpo-43323.9mFPuI.rst @@ -0,0 +1,2 @@ +Fix errors in the :mod:`email` module if the charset itself contains +undecodable/unencodable characters. From e8ff3c92f69b475aa20ba7c08efccbc329f9b42e Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 30 Apr 2022 15:33:39 +0300 Subject: [PATCH 106/237] [3.10] gh-92049: Forbid pickling constants re._constants.SUCCESS etc (GH-92070) (GH-92073) Previously, pickling did not fail, but the result could not be unpickled. (cherry picked from commit 6d0d547033e295f91f05030322acfbb0e280fc1f) --- Lib/sre_constants.py | 2 ++ .../next/Library/2022-04-30-10-53-10.gh-issue-92049.5SEKoh.rst | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2022-04-30-10-53-10.gh-issue-92049.5SEKoh.rst diff --git a/Lib/sre_constants.py b/Lib/sre_constants.py index 8e613cb3fa5dcb..db3ca51e8306ad 100644 --- a/Lib/sre_constants.py +++ b/Lib/sre_constants.py @@ -62,6 +62,8 @@ def __new__(cls, value, name): def __repr__(self): return self.name + __reduce__ = None + MAXREPEAT = _NamedIntConstant(MAXREPEAT, 'MAXREPEAT') def _makecodes(names): diff --git a/Misc/NEWS.d/next/Library/2022-04-30-10-53-10.gh-issue-92049.5SEKoh.rst b/Misc/NEWS.d/next/Library/2022-04-30-10-53-10.gh-issue-92049.5SEKoh.rst new file mode 100644 index 00000000000000..cad4621c65096c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-30-10-53-10.gh-issue-92049.5SEKoh.rst @@ -0,0 +1,2 @@ +Forbid pickling constants ``re._constants.SUCCESS`` etc. Previously, +pickling did not fail, but the result could not be unpickled. From 5ed9556cfbcfddc64e5e928b0f6ff1908553fcae Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 30 Apr 2022 08:39:29 -0700 Subject: [PATCH 107/237] gh-85864: io docs: Add missing position-only parameters (GH-91950) (cherry picked from commit 3a8e2b6e65fea1252477f6e29a384fa9a492ed06) Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> --- Doc/library/io.rst | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Doc/library/io.rst b/Doc/library/io.rst index b566d0c42499db..c125ec2aa2e677 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -396,7 +396,7 @@ I/O Base Classes Note that it's already possible to iterate on file objects using ``for line in file: ...`` without calling ``file.readlines()``. - .. method:: seek(offset, whence=SEEK_SET) + .. method:: seek(offset, whence=SEEK_SET, /) Change the stream position to the given byte *offset*. *offset* is interpreted relative to the position indicated by *whence*. The default @@ -428,7 +428,7 @@ I/O Base Classes Return the current stream position. - .. method:: truncate(size=None) + .. method:: truncate(size=None, /) Resize the stream to the given *size* in bytes (or the current position if *size* is not specified). The current stream position isn't changed. @@ -445,7 +445,7 @@ I/O Base Classes Return ``True`` if the stream supports writing. If ``False``, :meth:`write` and :meth:`truncate` will raise :exc:`OSError`. - .. method:: writelines(lines) + .. method:: writelines(lines, /) Write a list of lines to the stream. Line separators are not added, so it is usual for each of the lines provided to have a line separator at the @@ -489,7 +489,7 @@ I/O Base Classes Read and return all the bytes from the stream until EOF, using multiple calls to the stream if necessary. - .. method:: readinto(b) + .. method:: readinto(b, /) Read bytes into a pre-allocated, writable :term:`bytes-like object` *b*, and return the @@ -497,7 +497,7 @@ I/O Base Classes If the object is in non-blocking mode and no bytes are available, ``None`` is returned. - .. method:: write(b) + .. method:: write(b, /) Write the given :term:`bytes-like object`, *b*, to the underlying raw stream, and return the number of @@ -554,7 +554,7 @@ I/O Base Classes .. versionadded:: 3.1 - .. method:: read(size=-1) + .. method:: read(size=-1, /) Read and return up to *size* bytes. If the argument is omitted, ``None``, or negative, data is read and returned until EOF is reached. An empty @@ -569,7 +569,7 @@ I/O Base Classes A :exc:`BlockingIOError` is raised if the underlying raw stream is in non blocking-mode, and has no data available at the moment. - .. method:: read1([size]) + .. method:: read1(size=-1, /) Read and return up to *size* bytes, with at most one call to the underlying raw stream's :meth:`~RawIOBase.read` (or @@ -604,7 +604,7 @@ I/O Base Classes .. versionadded:: 3.5 - .. method:: write(b) + .. method:: write(b, /) Write the given :term:`bytes-like object`, *b*, and return the number of bytes written (always equal to the length of *b* in bytes, since if @@ -687,7 +687,7 @@ Buffered Streams Buffered I/O streams provide a higher-level interface to an I/O device than raw I/O does. -.. class:: BytesIO([initial_bytes]) +.. class:: BytesIO(initial_bytes=b'') A binary stream using an in-memory bytes buffer. It inherits :class:`BufferedIOBase`. The buffer is discarded when the @@ -722,14 +722,14 @@ than raw I/O does. Return :class:`bytes` containing the entire contents of the buffer. - .. method:: read1([size], /) + .. method:: read1(size=-1, /) In :class:`BytesIO`, this is the same as :meth:`~BufferedIOBase.read`. .. versionchanged:: 3.7 The *size* argument is now optional. - .. method:: readinto1(b) + .. method:: readinto1(b, /) In :class:`BytesIO`, this is the same as :meth:`~BufferedIOBase.readinto`. @@ -752,18 +752,18 @@ than raw I/O does. :class:`BufferedReader` provides or overrides these methods in addition to those from :class:`BufferedIOBase` and :class:`IOBase`: - .. method:: peek([size]) + .. method:: peek(size=0, /) Return bytes from the stream without advancing the position. At most one single read on the raw stream is done to satisfy the call. The number of bytes returned may be less or more than requested. - .. method:: read([size]) + .. method:: read(size=-1, /) Read and return *size* bytes, or if *size* is not given or negative, until EOF or if the read call would block in non-blocking mode. - .. method:: read1([size]) + .. method:: read1(size=-1, /) Read and return up to *size* bytes with only one call on the raw stream. If at least one byte is buffered, only buffered bytes are returned. @@ -895,14 +895,14 @@ Text I/O Read and return at most *size* characters from the stream as a single :class:`str`. If *size* is negative or ``None``, reads until EOF. - .. method:: readline(size=-1) + .. method:: readline(size=-1, /) Read until newline or EOF and return a single ``str``. If the stream is already at EOF, an empty string is returned. If *size* is specified, at most *size* characters will be read. - .. method:: seek(offset, whence=SEEK_SET) + .. method:: seek(offset, whence=SEEK_SET, /) Change the stream position to the given *offset*. Behaviour depends on the *whence* parameter. The default value for *whence* is @@ -929,7 +929,7 @@ Text I/O does not usually represent a number of bytes in the underlying binary storage. - .. method:: write(s) + .. method:: write(s, /) Write the string *s* to the stream and return the number of characters written. From cfcda0acf27e40eab38c1c7c542362d872f6b403 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 30 Apr 2022 14:44:08 -0700 Subject: [PATCH 108/237] gh-87192: Update wording for fcntl 'Changed in' (GH-91658) (cherry picked from commit d7eb1ffbe8f913693e4c9ffa1b32edccac987ab6) Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> --- Doc/library/fcntl.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst index 9d8021150c42f5..d9b579fc47d3d8 100644 --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -37,7 +37,8 @@ descriptor. On macOS, the fcntl module exposes the ``F_GETPATH`` constant, which obtains the path of a file from a file descriptor. On Linux(>=3.15), the fcntl module exposes the ``F_OFD_GETLK``, ``F_OFD_SETLK`` - and ``F_OFD_SETLKW`` constants, which working with open file description locks. + and ``F_OFD_SETLKW`` constants, which are used when working with open file + description locks. .. versionchanged:: 3.10 On Linux >= 2.6.11, the fcntl module exposes the ``F_GETPIPE_SZ`` and From 335aae195093d89d11f4379d36c663233abead61 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 30 Apr 2022 14:51:45 -0700 Subject: [PATCH 109/237] gh-87801: Add run() to subprocess.CalledProcessError description (GH-91628) (cherry picked from commit 567be058b403db9689af45bf831d4c732c8b1105) Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> --- Doc/library/subprocess.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index ab9f1d88a0fc26..4d3312077bbd09 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -214,7 +214,9 @@ compatibility with older versions, see the :ref:`call-function-trio` section. .. exception:: CalledProcessError Subclass of :exc:`SubprocessError`, raised when a process run by - :func:`check_call` or :func:`check_output` returns a non-zero exit status. + :func:`check_call`, :func:`check_output`, or :func:`run` (with ``check=True``) + returns a non-zero exit status. + .. attribute:: returncode From 8b6e5d38636807850e6b9579a98117b71b116e97 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 30 Apr 2022 15:29:09 -0700 Subject: [PATCH 110/237] gh-89253: Add 3.10 whatsnew section for itertools.pairwise (GH-91563) GH-89253 [`pairwise()`](https://docs.python.org/3/library/itertools.htmlGH-itertools.pairwise) already has the 'new in python3.10' Automerge-Triggered-By: GH:rhettinger (cherry picked from commit 5dcfb916c765d825b2e8372281d71d32316b41cf) Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> --- Doc/whatsnew/3.10.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 5788e32da1c928..55e7d62b541597 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -1212,6 +1212,12 @@ now call :func:`inspect.get_annotations` to retrieve annotations. This means also now un-stringize stringized annotations. (Contributed by Larry Hastings in :issue:`43817`.) +itertools +--------- + +Add :func:`itertools.pairwise()`. +(Contributed by Raymond Hettinger in :issue:`38200`.) + linecache --------- From 31e35bef22e6cf21526b1099c650e97a0a5c6652 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 30 Apr 2022 21:03:11 -0700 Subject: [PATCH 111/237] gh-91611: Use example.com for documentation, not mydomain.com (GH-91613) example.com is reserved by the IANA as special-use domain name for documentation purposes. The domain names are used widely in books, tutorials, sample network configurations, and generally as examples for the use of domain name. On the other hand, mydomain.com is real Domain Name Registration service. (cherry picked from commit ea392467829d6e93f824bde8eb87bdb31d9e4c62) Co-authored-by: Motoki Naruse --- Doc/library/secrets.rst | 2 +- Doc/library/ssl.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/secrets.rst b/Doc/library/secrets.rst index afa8e2d385fa46..c22da727b55c9b 100644 --- a/Doc/library/secrets.rst +++ b/Doc/library/secrets.rst @@ -193,7 +193,7 @@ suitable for password recovery applications: .. testcode:: import secrets - url = 'https://mydomain.com/reset=' + secrets.token_urlsafe() + url = 'https://example.com/reset=' + secrets.token_urlsafe() diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index d21d6122e0a801..19d983bcfe28df 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -2357,7 +2357,7 @@ waiting for clients to connect:: context.load_cert_chain(certfile="mycertfile", keyfile="mykeyfile") bindsocket = socket.socket() - bindsocket.bind(('myaddr.mydomain.com', 10023)) + bindsocket.bind(('myaddr.example.com', 10023)) bindsocket.listen(5) When a client connects, you'll call :meth:`accept` on the socket to get the From a48d31f204642c8b38e55dd78c4839bb7ae5dce9 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 30 Apr 2022 21:21:51 -0700 Subject: [PATCH 112/237] gh-81488: Add recursive wording for issubclass docs (GH-92087) (cherry picked from commit 1066ecb97042b8e89de554e6f9dc2e3d634208c0) Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> --- Doc/library/functions.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 42fbf4e6f969cd..ff81558da14cf8 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -913,7 +913,8 @@ are always available. They are listed here in alphabetical order. Return ``True`` if *class* is a subclass (direct, indirect, or :term:`virtual `) of *classinfo*. A class is considered a subclass of itself. *classinfo* may be a tuple of class - objects or a :ref:`types-union`, in which case return ``True`` if *class* is a + objects (or recursively, other such tuples) + or a :ref:`types-union`, in which case return ``True`` if *class* is a subclass of any entry in *classinfo*. In any other case, a :exc:`TypeError` exception is raised. From e7de54321952ebb58cc414f2160c9ad4f6510af2 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 30 Apr 2022 21:55:58 -0700 Subject: [PATCH 113/237] typing docs: Add example for async functions (GH-20386) Fixes python/typingGH-424 (cherry picked from commit 9588f880a286a8cc5597188f6ab44108c8f18761) Co-authored-by: Sam Bull --- Doc/library/typing.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 36d637f3665092..6a160af895c064 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -211,6 +211,10 @@ For example:: on_error: Callable[[int, Exception], None]) -> None: # Body + async def on_update(value: str) -> None: + # Body + callback: Callable[[str], Awaitable[None]] = on_update + It is possible to declare the return type of a callable without specifying the call signature by substituting a literal ellipsis for the list of arguments in the type hint: ``Callable[..., ReturnType]``. From ea1eba03e7e8401d5acf8b30b56b41faa209e8c6 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Sun, 1 May 2022 16:09:50 -0700 Subject: [PATCH 114/237] [3.10] gh-91401: Conservative backport of `subprocess._USE_VFORK` (#91932) This does not alter the `_posixsubprocess.fork_exec()` private API to avoid issues for anyone relying on that (bad idea) or for anyone who's `subprocess.py` and `_posixsubprocess.so` upgrades may not become visible to existing Python 3.10 processes at the same time. Backports the concept of cd5726fe674eaff442510eeb6c75628858be9e9f. Provides a fail-safe way to disable vfork for #91401. I didn't backport the documentation as I don't actually expect this to be used and `.. versionadded: 3.10.5` always looks weird in docs. It's being done more to have a fail-safe in place for people just in case. --- Lib/subprocess.py | 3 +++ Lib/test/test_subprocess.py | 22 +++++++++++++++ ...2-04-26-00-10-06.gh-issue-91401.mddRC8.rst | 5 ++++ Modules/_posixsubprocess.c | 27 +++++++++++++++++-- 4 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-04-26-00-10-06.gh-issue-91401.mddRC8.rst diff --git a/Lib/subprocess.py b/Lib/subprocess.py index ccb46a6337b3d9..a414321b9d197e 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -691,7 +691,10 @@ def _use_posix_spawn(): return False +# These are primarily fail-safe knobs for negatives. A True value does not +# guarantee the given libc/syscall API will be used. _USE_POSIX_SPAWN = _use_posix_spawn() +_USE_VFORK = True class Popen: diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index 7bb049296912b9..b91791a02a2e52 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -1702,6 +1702,28 @@ def test_run_with_shell_timeout_and_capture_output(self): msg="TimeoutExpired was delayed! Bad traceback:\n```\n" f"{stacks}```") + @unittest.skipIf(not sysconfig.get_config_var("HAVE_VFORK"), + "vfork() not enabled by configure.") + def test__use_vfork(self): + # Attempts code coverage within _posixsubprocess.c on the code that + # probes the subprocess module for the existence and value of this + # attribute in 3.10.5. + self.assertTrue(subprocess._USE_VFORK) # The default value regardless. + with mock.patch.object(subprocess, "_USE_VFORK", False): + self.assertEqual(self.run_python("pass").returncode, 0, + msg="False _USE_VFORK failed") + + class RaisingBool: + def __bool__(self): + raise RuntimeError("force PyObject_IsTrue to return -1") + + with mock.patch.object(subprocess, "_USE_VFORK", RaisingBool()): + self.assertEqual(self.run_python("pass").returncode, 0, + msg="odd bool()-error _USE_VFORK failed") + del subprocess._USE_VFORK + self.assertEqual(self.run_python("pass").returncode, 0, + msg="lack of a _USE_VFORK attribute failed") + def _get_test_grp_name(): for name_group in ('staff', 'nogroup', 'grp', 'nobody', 'nfsnobody'): diff --git a/Misc/NEWS.d/next/Library/2022-04-26-00-10-06.gh-issue-91401.mddRC8.rst b/Misc/NEWS.d/next/Library/2022-04-26-00-10-06.gh-issue-91401.mddRC8.rst new file mode 100644 index 00000000000000..964a54f8935c2e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-26-00-10-06.gh-issue-91401.mddRC8.rst @@ -0,0 +1,5 @@ +Provide a fail-safe way to disable :mod:`subprocess` use of ``vfork()`` via +a private ``subprocess._USE_VFORK`` attribute. While there is currently no +known need for this, if you find a need please only set it to ``False``. +File a CPython issue as to why you needed it and link to that from a +comment in your code. This attribute is documented as a footnote in 3.11. diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index 18a81c6ed8b353..b852ad71d72251 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -936,8 +936,31 @@ subprocess_fork_exec(PyObject *module, PyObject *args) #ifdef VFORK_USABLE /* Use vfork() only if it's safe. See the comment above child_exec(). */ sigset_t old_sigs; - if (preexec_fn == Py_None && - !call_setuid && !call_setgid && !call_setgroups) { + int allow_vfork; + if (preexec_fn == Py_None) { + allow_vfork = 1; /* 3.10.0 behavior */ + PyObject *subprocess_module = PyImport_ImportModule("subprocess"); + if (subprocess_module != NULL) { + PyObject *allow_vfork_obj = PyObject_GetAttrString( + subprocess_module, "_USE_VFORK"); + Py_DECREF(subprocess_module); + if (allow_vfork_obj != NULL) { + allow_vfork = PyObject_IsTrue(allow_vfork_obj); + Py_DECREF(allow_vfork_obj); + if (allow_vfork < 0) { + PyErr_Clear(); /* Bad _USE_VFORK attribute. */ + allow_vfork = 1; /* 3.10.0 behavior */ + } + } else { + PyErr_Clear(); /* No _USE_VFORK attribute. */ + } + } else { + PyErr_Clear(); /* no subprocess module? suspicious; don't care. */ + } + } else { + allow_vfork = 0; + } + if (allow_vfork && !call_setuid && !call_setgid && !call_setgroups) { /* Block all signals to ensure that no signal handlers are run in the * child process while it shares memory with us. Note that signals * used internally by C libraries won't be blocked by From 1fd3ab7c28451f7346c7e911e265ad74f6086d19 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sun, 1 May 2022 17:46:06 -0600 Subject: [PATCH 115/237] [3.10] build(deps): bump actions/stale from 4 to 5 (GH-92108) (#92127) Bumps [actions/stale](https://github.com/actions/stale) from 4 to 5. - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/stale dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>. (cherry picked from commit 34129f7c42b31d12d8ed692cd3f82c8d36c6c644) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/stale.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 26806fad814f1a..4a08ef0d8dac5f 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -13,7 +13,8 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/stale@v3 + - name: "Check PRs" + uses: actions/stale@v5 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-pr-message: 'This PR is stale because it has been open for 30 days with no activity.' From a7d3de7fe650d393d63039cb0ed7c1320d050345 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 2 May 2022 01:45:10 -0700 Subject: [PATCH 116/237] gh-85679: Recommend `encoding="utf-8"` in tutorial (GH-91778) (cherry picked from commit 614420df9796c8a4f01e24052fc0128b4c20c5bf) Co-authored-by: Inada Naoki --- Doc/tutorial/inputoutput.rst | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/Doc/tutorial/inputoutput.rst b/Doc/tutorial/inputoutput.rst index 7f83c4d4612eb3..b50063654e2628 100644 --- a/Doc/tutorial/inputoutput.rst +++ b/Doc/tutorial/inputoutput.rst @@ -279,11 +279,12 @@ Reading and Writing Files object: file :func:`open` returns a :term:`file object`, and is most commonly used with -two arguments: ``open(filename, mode)``. +two positional arguments and one keyword argument: +``open(filename, mode, encoding=None)`` :: - >>> f = open('workfile', 'w') + >>> f = open('workfile', 'w', encoding="utf-8") .. XXX str(f) is @@ -300,11 +301,14 @@ writing. The *mode* argument is optional; ``'r'`` will be assumed if it's omitted. Normally, files are opened in :dfn:`text mode`, that means, you read and write -strings from and to the file, which are encoded in a specific encoding. If -encoding is not specified, the default is platform dependent (see -:func:`open`). ``'b'`` appended to the mode opens the file in -:dfn:`binary mode`: now the data is read and written in the form of bytes -objects. This mode should be used for all files that don't contain text. +strings from and to the file, which are encoded in a specific *encoding*. +If *encoding* is not specified, the default is platform dependent +(see :func:`open`). +Because UTF-8 is the modern de-facto standard, ``encoding="utf-8"`` is +recommended unless you know that you need to use a different encoding. +Appending a ``'b'`` to the mode opens the file in :dfn:`binary mode`. +Binary mode data is read and written as :class:`bytes` objects. +You can not specify *encoding* when opening file in binary mode. In text mode, the default when reading is to convert platform-specific line endings (``\n`` on Unix, ``\r\n`` on Windows) to just ``\n``. When writing in @@ -320,7 +324,7 @@ after its suite finishes, even if an exception is raised at some point. Using :keyword:`!with` is also much shorter than writing equivalent :keyword:`try`\ -\ :keyword:`finally` blocks:: - >>> with open('workfile') as f: + >>> with open('workfile', encoding="utf-8") as f: ... read_data = f.read() >>> # We can check that the file has been automatically closed. @@ -490,11 +494,15 @@ simply serializes the object to a :term:`text file`. So if ``f`` is a json.dump(x, f) -To decode the object again, if ``f`` is a :term:`text file` object which has -been opened for reading:: +To decode the object again, if ``f`` is a :term:`binary file` or +:term:`text file` object which has been opened for reading:: x = json.load(f) +.. note:: + JSON files must be encoded in UTF-8. Use ``encoding="utf-8"`` when opening + JSON file as a :term:`text file` for both of reading and writing. + This simple serialization technique can handle lists and dictionaries, but serializing arbitrary class instances in JSON requires a bit of extra effort. The reference for the :mod:`json` module contains an explanation of this. From d985c8e2e0d38e6905cc27124008eb926254247b Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 2 May 2022 02:58:41 -0700 Subject: [PATCH 117/237] bpo-36819: Fix crashes in built-in encoders with weird error handlers (GH-28593) If the error handler returns position less or equal than the starting position of non-encodable characters, most of built-in encoders didn't properly re-size the output buffer. This led to out-of-bounds writes, and segfaults. (cherry picked from commit 18b07d773e09a2719e69aeaa925d5abb7ba0c068) Co-authored-by: Serhiy Storchaka --- Lib/test/test_codeccallbacks.py | 177 +++++++++++++++++- .../2021-09-28-10-58-30.bpo-36819.cyV50C.rst | 2 + Objects/stringlib/codecs.h | 15 +- Objects/unicodeobject.c | 60 +++--- 4 files changed, 222 insertions(+), 32 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2021-09-28-10-58-30.bpo-36819.cyV50C.rst diff --git a/Lib/test/test_codeccallbacks.py b/Lib/test/test_codeccallbacks.py index 243f002c4ecadd..4991330489d139 100644 --- a/Lib/test/test_codeccallbacks.py +++ b/Lib/test/test_codeccallbacks.py @@ -1,5 +1,6 @@ import codecs import html.entities +import itertools import sys import unicodedata import unittest @@ -22,6 +23,18 @@ def handle(self, exc): self.pos = len(exc.object) return ("", oldpos) +class RepeatedPosReturn: + def __init__(self, repl=""): + self.repl = repl + self.pos = 0 + self.count = 0 + + def handle(self, exc): + if self.count > 0: + self.count -= 1 + return (self.repl, self.pos) + return (self.repl, exc.end) + # A UnicodeEncodeError object with a bad start attribute class BadStartUnicodeEncodeError(UnicodeEncodeError): def __init__(self): @@ -783,20 +796,104 @@ def test_lookup(self): codecs.lookup_error("namereplace") ) - def test_unencodablereplacement(self): + def test_encode_nonascii_replacement(self): + def handle(exc): + if isinstance(exc, UnicodeEncodeError): + return (repl, exc.end) + raise TypeError("don't know how to handle %r" % exc) + codecs.register_error("test.replacing", handle) + + for enc, input, repl in ( + ("ascii", "[¤]", "abc"), + ("iso-8859-1", "[€]", "½¾"), + ("iso-8859-15", "[¤]", "œŸ"), + ): + res = input.encode(enc, "test.replacing") + self.assertEqual(res, ("[" + repl + "]").encode(enc)) + + for enc, input, repl in ( + ("utf-8", "[\udc80]", "\U0001f40d"), + ("utf-16", "[\udc80]", "\U0001f40d"), + ("utf-32", "[\udc80]", "\U0001f40d"), + ): + with self.subTest(encoding=enc): + with self.assertRaises(UnicodeEncodeError) as cm: + input.encode(enc, "test.replacing") + exc = cm.exception + self.assertEqual(exc.start, 1) + self.assertEqual(exc.end, 2) + self.assertEqual(exc.object, input) + + def test_encode_unencodable_replacement(self): def unencrepl(exc): if isinstance(exc, UnicodeEncodeError): - return ("\u4242", exc.end) + return (repl, exc.end) else: raise TypeError("don't know how to handle %r" % exc) codecs.register_error("test.unencreplhandler", unencrepl) - for enc in ("ascii", "iso-8859-1", "iso-8859-15"): - self.assertRaises( - UnicodeEncodeError, - "\u4242".encode, - enc, - "test.unencreplhandler" - ) + + for enc, input, repl in ( + ("ascii", "[¤]", "½"), + ("iso-8859-1", "[€]", "œ"), + ("iso-8859-15", "[¤]", "½"), + ("utf-8", "[\udc80]", "\udcff"), + ("utf-16", "[\udc80]", "\udcff"), + ("utf-32", "[\udc80]", "\udcff"), + ): + with self.subTest(encoding=enc): + with self.assertRaises(UnicodeEncodeError) as cm: + input.encode(enc, "test.unencreplhandler") + exc = cm.exception + self.assertEqual(exc.start, 1) + self.assertEqual(exc.end, 2) + self.assertEqual(exc.object, input) + + def test_encode_bytes_replacement(self): + def handle(exc): + if isinstance(exc, UnicodeEncodeError): + return (repl, exc.end) + raise TypeError("don't know how to handle %r" % exc) + codecs.register_error("test.replacing", handle) + + # It works even if the bytes sequence is not decodable. + for enc, input, repl in ( + ("ascii", "[¤]", b"\xbd\xbe"), + ("iso-8859-1", "[€]", b"\xbd\xbe"), + ("iso-8859-15", "[¤]", b"\xbd\xbe"), + ("utf-8", "[\udc80]", b"\xbd\xbe"), + ("utf-16le", "[\udc80]", b"\xbd\xbe"), + ("utf-16be", "[\udc80]", b"\xbd\xbe"), + ("utf-32le", "[\udc80]", b"\xbc\xbd\xbe\xbf"), + ("utf-32be", "[\udc80]", b"\xbc\xbd\xbe\xbf"), + ): + with self.subTest(encoding=enc): + res = input.encode(enc, "test.replacing") + self.assertEqual(res, "[".encode(enc) + repl + "]".encode(enc)) + + def test_encode_odd_bytes_replacement(self): + def handle(exc): + if isinstance(exc, UnicodeEncodeError): + return (repl, exc.end) + raise TypeError("don't know how to handle %r" % exc) + codecs.register_error("test.replacing", handle) + + input = "[\udc80]" + # Tests in which the replacement bytestring contains not whole number + # of code units. + for enc, repl in ( + *itertools.product(("utf-16le", "utf-16be"), + [b"a", b"abc"]), + *itertools.product(("utf-32le", "utf-32be"), + [b"a", b"ab", b"abc", b"abcde"]), + ): + with self.subTest(encoding=enc, repl=repl): + with self.assertRaises(UnicodeEncodeError) as cm: + input.encode(enc, "test.replacing") + exc = cm.exception + self.assertEqual(exc.start, 1) + self.assertEqual(exc.end, 2) + self.assertEqual(exc.object, input) + self.assertEqual(exc.reason, "surrogates not allowed") def test_badregistercall(self): # enhance coverage of: @@ -940,6 +1037,68 @@ def __getitem__(self, key): self.assertRaises(ValueError, codecs.charmap_encode, "\xff", err, D()) self.assertRaises(TypeError, codecs.charmap_encode, "\xff", err, {0xff: 300}) + def test_decodehelper_bug36819(self): + handler = RepeatedPosReturn("x") + codecs.register_error("test.bug36819", handler.handle) + + testcases = [ + ("ascii", b"\xff"), + ("utf-8", b"\xff"), + ("utf-16be", b'\xdc\x80'), + ("utf-32be", b'\x00\x00\xdc\x80'), + ("iso-8859-6", b"\xff"), + ] + for enc, bad in testcases: + input = "abcd".encode(enc) + bad + with self.subTest(encoding=enc): + handler.count = 50 + decoded = input.decode(enc, "test.bug36819") + self.assertEqual(decoded, 'abcdx' * 51) + + def test_encodehelper_bug36819(self): + handler = RepeatedPosReturn() + codecs.register_error("test.bug36819", handler.handle) + + input = "abcd\udc80" + encodings = ["ascii", "latin1", "utf-8", "utf-16", "utf-32"] # built-in + encodings += ["iso-8859-15"] # charmap codec + if sys.platform == 'win32': + encodings = ["mbcs", "oem"] # code page codecs + + handler.repl = "\udcff" + for enc in encodings: + with self.subTest(encoding=enc): + handler.count = 50 + with self.assertRaises(UnicodeEncodeError) as cm: + input.encode(enc, "test.bug36819") + exc = cm.exception + self.assertEqual(exc.start, 4) + self.assertEqual(exc.end, 5) + self.assertEqual(exc.object, input) + if sys.platform == "win32": + handler.count = 50 + with self.assertRaises(UnicodeEncodeError) as cm: + codecs.code_page_encode(437, input, "test.bug36819") + exc = cm.exception + self.assertEqual(exc.start, 4) + self.assertEqual(exc.end, 5) + self.assertEqual(exc.object, input) + + handler.repl = "x" + for enc in encodings: + with self.subTest(encoding=enc): + # The interpreter should segfault after a handful of attempts. + # 50 was chosen to try to ensure a segfault without a fix, + # but not OOM a machine with one. + handler.count = 50 + encoded = input.encode(enc, "test.bug36819") + self.assertEqual(encoded.decode(enc), "abcdx" * 51) + if sys.platform == "win32": + handler.count = 50 + encoded = codecs.code_page_encode(437, input, "test.bug36819") + self.assertEqual(encoded[0].decode(), "abcdx" * 51) + self.assertEqual(encoded[1], len(input)) + def test_translatehelper(self): # enhance coverage of: # Objects/unicodeobject.c::unicode_encode_call_errorhandler() diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-09-28-10-58-30.bpo-36819.cyV50C.rst b/Misc/NEWS.d/next/Core and Builtins/2021-09-28-10-58-30.bpo-36819.cyV50C.rst new file mode 100644 index 00000000000000..32bb55a90e6c4d --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2021-09-28-10-58-30.bpo-36819.cyV50C.rst @@ -0,0 +1,2 @@ +Fix crashes in built-in encoders with error handlers that return position +less or equal than the starting position of non-encodable characters. diff --git a/Objects/stringlib/codecs.h b/Objects/stringlib/codecs.h index b17cda18f54b3e..958cc86147815d 100644 --- a/Objects/stringlib/codecs.h +++ b/Objects/stringlib/codecs.h @@ -387,8 +387,19 @@ STRINGLIB(utf8_encoder)(_PyBytesWriter *writer, if (!rep) goto error; - /* subtract preallocated bytes */ - writer->min_size -= max_char_size * (newpos - startpos); + if (newpos < startpos) { + writer->overallocate = 1; + p = _PyBytesWriter_Prepare(writer, p, + max_char_size * (startpos - newpos)); + if (p == NULL) + goto error; + } + else { + /* subtract preallocated bytes */ + writer->min_size -= max_char_size * (newpos - startpos); + /* Only overallocate the buffer if it's not the last write */ + writer->overallocate = (newpos < size); + } if (PyBytes_Check(rep)) { p = _PyBytesWriter_WriteBytes(writer, p, diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 5ddde5054428a2..b7ec1f28d7e862 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -5959,7 +5959,7 @@ _PyUnicode_EncodeUTF32(PyObject *str, pos = 0; while (pos < len) { - Py_ssize_t repsize, moreunits; + Py_ssize_t newpos, repsize, moreunits; if (kind == PyUnicode_2BYTE_KIND) { pos += ucs2lib_utf32_encode((const Py_UCS2 *)data + pos, len - pos, @@ -5976,7 +5976,7 @@ _PyUnicode_EncodeUTF32(PyObject *str, rep = unicode_encode_call_errorhandler( errors, &errorHandler, encoding, "surrogates not allowed", - str, &exc, pos, pos + 1, &pos); + str, &exc, pos, pos + 1, &newpos); if (!rep) goto error; @@ -5984,7 +5984,7 @@ _PyUnicode_EncodeUTF32(PyObject *str, repsize = PyBytes_GET_SIZE(rep); if (repsize & 3) { raise_encode_exception(&exc, encoding, - str, pos - 1, pos, + str, pos, pos + 1, "surrogates not allowed"); goto error; } @@ -5997,28 +5997,30 @@ _PyUnicode_EncodeUTF32(PyObject *str, moreunits = repsize = PyUnicode_GET_LENGTH(rep); if (!PyUnicode_IS_ASCII(rep)) { raise_encode_exception(&exc, encoding, - str, pos - 1, pos, + str, pos, pos + 1, "surrogates not allowed"); goto error; } } + moreunits += pos - newpos; + pos = newpos; /* four bytes are reserved for each surrogate */ - if (moreunits > 1) { + if (moreunits > 0) { Py_ssize_t outpos = out - (uint32_t*) PyBytes_AS_STRING(v); if (moreunits >= (PY_SSIZE_T_MAX - PyBytes_GET_SIZE(v)) / 4) { /* integer overflow */ PyErr_NoMemory(); goto error; } - if (_PyBytes_Resize(&v, PyBytes_GET_SIZE(v) + 4 * (moreunits - 1)) < 0) + if (_PyBytes_Resize(&v, PyBytes_GET_SIZE(v) + 4 * moreunits) < 0) goto error; out = (uint32_t*) PyBytes_AS_STRING(v) + outpos; } if (PyBytes_Check(rep)) { memcpy(out, PyBytes_AS_STRING(rep), repsize); - out += moreunits; + out += repsize / 4; } else /* rep is unicode */ { assert(PyUnicode_KIND(rep) == PyUnicode_1BYTE_KIND); ucs1lib_utf32_encode(PyUnicode_1BYTE_DATA(rep), repsize, @@ -6311,7 +6313,7 @@ _PyUnicode_EncodeUTF16(PyObject *str, pos = 0; while (pos < len) { - Py_ssize_t repsize, moreunits; + Py_ssize_t newpos, repsize, moreunits; if (kind == PyUnicode_2BYTE_KIND) { pos += ucs2lib_utf16_encode((const Py_UCS2 *)data + pos, len - pos, @@ -6328,7 +6330,7 @@ _PyUnicode_EncodeUTF16(PyObject *str, rep = unicode_encode_call_errorhandler( errors, &errorHandler, encoding, "surrogates not allowed", - str, &exc, pos, pos + 1, &pos); + str, &exc, pos, pos + 1, &newpos); if (!rep) goto error; @@ -6336,7 +6338,7 @@ _PyUnicode_EncodeUTF16(PyObject *str, repsize = PyBytes_GET_SIZE(rep); if (repsize & 1) { raise_encode_exception(&exc, encoding, - str, pos - 1, pos, + str, pos, pos + 1, "surrogates not allowed"); goto error; } @@ -6349,28 +6351,30 @@ _PyUnicode_EncodeUTF16(PyObject *str, moreunits = repsize = PyUnicode_GET_LENGTH(rep); if (!PyUnicode_IS_ASCII(rep)) { raise_encode_exception(&exc, encoding, - str, pos - 1, pos, + str, pos, pos + 1, "surrogates not allowed"); goto error; } } + moreunits += pos - newpos; + pos = newpos; /* two bytes are reserved for each surrogate */ - if (moreunits > 1) { + if (moreunits > 0) { Py_ssize_t outpos = out - (unsigned short*) PyBytes_AS_STRING(v); if (moreunits >= (PY_SSIZE_T_MAX - PyBytes_GET_SIZE(v)) / 2) { /* integer overflow */ PyErr_NoMemory(); goto error; } - if (_PyBytes_Resize(&v, PyBytes_GET_SIZE(v) + 2 * (moreunits - 1)) < 0) + if (_PyBytes_Resize(&v, PyBytes_GET_SIZE(v) + 2 * moreunits) < 0) goto error; out = (unsigned short*) PyBytes_AS_STRING(v) + outpos; } if (PyBytes_Check(rep)) { memcpy(out, PyBytes_AS_STRING(rep), repsize); - out += moreunits; + out += repsize / 2; } else /* rep is unicode */ { assert(PyUnicode_KIND(rep) == PyUnicode_1BYTE_KIND); ucs1lib_utf16_encode(PyUnicode_1BYTE_DATA(rep), repsize, @@ -7297,8 +7301,19 @@ unicode_encode_ucs1(PyObject *unicode, if (rep == NULL) goto onError; - /* subtract preallocated bytes */ - writer.min_size -= newpos - collstart; + if (newpos < collstart) { + writer.overallocate = 1; + str = _PyBytesWriter_Prepare(&writer, str, + collstart - newpos); + if (str == NULL) + goto onError; + } + else { + /* subtract preallocated bytes */ + writer.min_size -= newpos - collstart; + /* Only overallocate the buffer if it's not the last write */ + writer.overallocate = (newpos < size); + } if (PyBytes_Check(rep)) { /* Directly copy bytes result to output. */ @@ -8104,13 +8119,14 @@ encode_code_page_errors(UINT code_page, PyObject **outbytes, pos, pos + 1, &newpos); if (rep == NULL) goto error; - pos = newpos; + Py_ssize_t morebytes = pos - newpos; if (PyBytes_Check(rep)) { outsize = PyBytes_GET_SIZE(rep); - if (outsize != 1) { + morebytes += outsize; + if (morebytes > 0) { Py_ssize_t offset = out - PyBytes_AS_STRING(*outbytes); - newoutsize = PyBytes_GET_SIZE(*outbytes) + (outsize - 1); + newoutsize = PyBytes_GET_SIZE(*outbytes) + morebytes; if (_PyBytes_Resize(outbytes, newoutsize) < 0) { Py_DECREF(rep); goto error; @@ -8131,9 +8147,10 @@ encode_code_page_errors(UINT code_page, PyObject **outbytes, } outsize = PyUnicode_GET_LENGTH(rep); - if (outsize != 1) { + morebytes += outsize; + if (morebytes > 0) { Py_ssize_t offset = out - PyBytes_AS_STRING(*outbytes); - newoutsize = PyBytes_GET_SIZE(*outbytes) + (outsize - 1); + newoutsize = PyBytes_GET_SIZE(*outbytes) + morebytes; if (_PyBytes_Resize(outbytes, newoutsize) < 0) { Py_DECREF(rep); goto error; @@ -8156,6 +8173,7 @@ encode_code_page_errors(UINT code_page, PyObject **outbytes, out++; } } + pos = newpos; Py_DECREF(rep); } /* write a NUL byte */ From bba721d0fa7832fd9dbdde44ba39f19755513303 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 2 May 2022 07:51:07 -0700 Subject: [PATCH 118/237] gh-84714: Add behavior if dst file exists (GH-91867) (cherry picked from commit 9166ace805d915c8a918cd89fff0e58b65e3327c) Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> --- Doc/library/shutil.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 8ce0e80ec81206..403df45b3966ad 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -160,7 +160,8 @@ Directory and files operations Copies the file *src* to the file or directory *dst*. *src* and *dst* should be :term:`path-like objects ` or strings. If *dst* specifies a directory, the file will be copied into *dst* using the - base filename from *src*. Returns the path to the newly created file. + base filename from *src*. If *dst* specifies a file that already exists, + it will be replaced. Returns the path to the newly created file. If *follow_symlinks* is false, and *src* is a symbolic link, *dst* will be created as a symbolic link. If *follow_symlinks* From 9ce39cc9f218da782949f6957b900fb8a8aa7a75 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 2 May 2022 07:58:09 -0700 Subject: [PATCH 119/237] gh-85133: os docs: Add that getenv uses os.environ (GH-91874) Co-authored-by: Jelle Zijlstra (cherry picked from commit b25352a5c039d95e019dd8ca111f6f77c43ca1f7) Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> --- Doc/library/os.rst | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/Doc/library/os.rst b/Doc/library/os.rst index b81574b7eaa469..1eaf369ff659a3 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -177,8 +177,8 @@ process and user. This mapping is captured the first time the :mod:`os` module is imported, typically during Python startup as part of processing :file:`site.py`. Changes - to the environment made after this time are not reflected in ``os.environ``, - except for changes made by modifying ``os.environ`` directly. + to the environment made after this time are not reflected in :data:`os.environ`, + except for changes made by modifying :data:`os.environ` directly. This mapping may be used to modify the environment as well as query the environment. :func:`putenv` will be called automatically when the mapping @@ -190,8 +190,8 @@ process and user. .. note:: - Calling :func:`putenv` directly does not change ``os.environ``, so it's better - to modify ``os.environ``. + Calling :func:`putenv` directly does not change :data:`os.environ`, so it's better + to modify :data:`os.environ`. .. note:: @@ -201,7 +201,7 @@ process and user. You can delete items in this mapping to unset environment variables. :func:`unsetenv` will be called automatically when an item is deleted from - ``os.environ``, and when one of the :meth:`pop` or :meth:`clear` methods is + :data:`os.environ`, and when one of the :meth:`pop` or :meth:`clear` methods is called. .. versionchanged:: 3.9 @@ -292,7 +292,10 @@ process and user. .. function:: getenv(key, default=None) Return the value of the environment variable *key* if it exists, or - *default* if it doesn't. *key*, *default* and the result are str. + *default* if it doesn't. *key*, *default* and the result are str. Note that + since :func:`getenv` uses :data:`os.environ`, the mapping of :func:`getenv` is + similarly also captured on import, and the function may not reflect + future environment changes. On Unix, keys and values are decoded with :func:`sys.getfilesystemencoding` and ``'surrogateescape'`` error handler. Use :func:`os.getenvb` if you @@ -304,7 +307,11 @@ process and user. .. function:: getenvb(key, default=None) Return the value of the environment variable *key* if it exists, or - *default* if it doesn't. *key*, *default* and the result are bytes. + *default* if it doesn't. *key*, *default* and the result are bytes. Note that + since :func:`getenvb` uses :data:`os.environb`, the mapping of :func:`getenvb` is + similarly also captured on import, and the function may not reflect + future environment changes. + :func:`getenvb` is only available if :data:`supports_bytes_environ` is ``True``. @@ -510,10 +517,11 @@ process and user. changes to the environment affect subprocesses started with :func:`os.system`, :func:`popen` or :func:`fork` and :func:`execv`. - Assignments to items in ``os.environ`` are automatically translated into + Assignments to items in :data:`os.environ` are automatically translated into corresponding calls to :func:`putenv`; however, calls to :func:`putenv` - don't update ``os.environ``, so it is actually preferable to assign to items - of ``os.environ``. + don't update :data:`os.environ`, so it is actually preferable to assign to items + of :data:`os.environ`. This also applies to :func:`getenv` and :func:`getenvb`, which + respectively use :data:`os.environ` and :data:`os.environb` in their implementations. .. note:: @@ -712,10 +720,10 @@ process and user. environment affect subprocesses started with :func:`os.system`, :func:`popen` or :func:`fork` and :func:`execv`. - Deletion of items in ``os.environ`` is automatically translated into a + Deletion of items in :data:`os.environ` is automatically translated into a corresponding call to :func:`unsetenv`; however, calls to :func:`unsetenv` - don't update ``os.environ``, so it is actually preferable to delete items of - ``os.environ``. + don't update :data:`os.environ`, so it is actually preferable to delete items of + :data:`os.environ`. .. audit-event:: os.unsetenv key os.unsetenv From 9941640041ef528dc6565ae7b2d1d26efdf8d19e Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 2 May 2022 08:18:01 -0700 Subject: [PATCH 120/237] asyncio.subprocess: Fix a typo in doc (GH-92030) Remove a confusion for read method in asyncio-subprocess doc for stderr StreamReader instance (cherry picked from commit bb857a96ef368ba9de1da2db12b1a1f1870606ac) Co-authored-by: Harsh <65716674+Harsh-br0@users.noreply.github.com> --- Doc/library/asyncio-subprocess.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/asyncio-subprocess.rst b/Doc/library/asyncio-subprocess.rst index 748b7040325549..e5000532a895dd 100644 --- a/Doc/library/asyncio-subprocess.rst +++ b/Doc/library/asyncio-subprocess.rst @@ -275,7 +275,7 @@ their completion. Use the :meth:`communicate` method rather than :attr:`process.stdin.write() `, :attr:`await process.stdout.read() ` or - :attr:`await process.stderr.read `. + :attr:`await process.stderr.read() `. This avoids deadlocks due to streams pausing reading or writing and blocking the child process. From 446cc037304e55e94c2e7492533f7b396c9c0e35 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 2 May 2022 08:35:37 -0700 Subject: [PATCH 121/237] gh-88546: glob.glob docs: Make new paragraph for emphasis and reordered sentence (GH-91614) (cherry picked from commit b9ab6cea0819bd498063f0934cb5bb0bb5a6a2d4) Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> --- Doc/library/glob.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Doc/library/glob.rst b/Doc/library/glob.rst index 215f60d328c76a..4a290473d89242 100644 --- a/Doc/library/glob.rst +++ b/Doc/library/glob.rst @@ -23,8 +23,11 @@ according to the rules used by the Unix shell, although results are returned in arbitrary order. No tilde expansion is done, but ``*``, ``?``, and character ranges expressed with ``[]`` will be correctly matched. This is done by using the :func:`os.scandir` and :func:`fnmatch.fnmatch` functions in concert, and -not by actually invoking a subshell. Note that unlike :func:`fnmatch.fnmatch`, -:mod:`glob` treats filenames beginning with a dot (``.``) as special cases. +not by actually invoking a subshell. + +Note that files beginning with a dot (``.``) can only be matched by +patterns that also start with a dot, +unlike :func:`fnmatch.fnmatch` or :func:`pathlib.Path.glob`. (For tilde and shell variable expansion, use :func:`os.path.expanduser` and :func:`os.path.expandvars`.) From ac508276dc8c9e1ac0731ec7fce3aae3a378ffd1 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 2 May 2022 09:06:43 -0700 Subject: [PATCH 122/237] concurrent.futures: Fix typo in docstring (GH-92121) (cherry picked from commit b11243e85e020ed2f524bdd83c339faf11ef03d4) Co-authored-by: Yiannis Hadjicharalambous --- Lib/concurrent/futures/_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py index 5c00f2edbe5482..cf119ac6437aa2 100644 --- a/Lib/concurrent/futures/_base.py +++ b/Lib/concurrent/futures/_base.py @@ -381,7 +381,7 @@ def running(self): return self._state == RUNNING def done(self): - """Return True of the future was cancelled or finished executing.""" + """Return True if the future was cancelled or finished executing.""" with self._condition: return self._state in [CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED] From 67120224473f12e62a16a6985b9864b5cc3d0aa4 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Mon, 2 May 2022 10:07:03 -0600 Subject: [PATCH 123/237] [3.10] build(deps): bump actions/cache from 3.0.1 to 3.0.2 (GH-92111) (#92124) Bumps [actions/cache](https://github.com/actions/cache) from 3.0.1 to 3.0.2. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.0.1...v3.0.2) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>. (cherry picked from commit eefe6911f4f497e8b73e0690f9b3f47904fdb02a) --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index adbe2fe1d248c1..61cbef982a9ef1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -196,7 +196,7 @@ jobs: echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV - name: 'Restore OpenSSL build' id: cache-openssl - uses: actions/cache@v3.0.1 + uses: actions/cache@v3.0.2 with: path: ./multissl/openssl/${{ env.OPENSSL_VER }} key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} @@ -244,7 +244,7 @@ jobs: echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV - name: 'Restore OpenSSL build' id: cache-openssl - uses: actions/cache@v3.0.1 + uses: actions/cache@v3.0.2 with: path: ./multissl/openssl/${{ env.OPENSSL_VER }} key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} From 178d79ae67848e129958172e8a9ca4838f8503b9 Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Mon, 2 May 2022 10:21:13 -0600 Subject: [PATCH 124/237] [3.10] gh-89301: Fix regression with bound values in traced SQLite statements (#92147) (cherry picked from commit 721aa96540bb96700f8c4bab0b4095b43491dca1) --- Lib/sqlite3/test/hooks.py | 26 ++++++++ .../2021-09-08-16-21-03.bpo-45138.yghUrK.rst | 3 + Modules/_sqlite/connection.c | 63 ++++++++++++++----- 3 files changed, 77 insertions(+), 15 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2021-09-08-16-21-03.bpo-45138.yghUrK.rst diff --git a/Lib/sqlite3/test/hooks.py b/Lib/sqlite3/test/hooks.py index 8c60bdcf5d70aa..97121eea1be5fb 100644 --- a/Lib/sqlite3/test/hooks.py +++ b/Lib/sqlite3/test/hooks.py @@ -20,6 +20,7 @@ # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. +import contextlib import unittest import sqlite3 as sqlite @@ -200,6 +201,16 @@ def progress(): self.assertEqual(action, 0, "progress handler was not cleared") class TraceCallbackTests(unittest.TestCase): + @contextlib.contextmanager + def check_stmt_trace(self, cx, expected): + try: + traced = [] + cx.set_trace_callback(lambda stmt: traced.append(stmt)) + yield + finally: + self.assertEqual(traced, expected) + cx.set_trace_callback(None) + def test_trace_callback_used(self): """ Test that the trace callback is invoked once it is set. @@ -261,6 +272,21 @@ def trace(statement): cur.execute(queries[1]) self.assertEqual(traced_statements, queries) + def test_trace_expanded_sql(self): + expected = [ + "create table t(t)", + "BEGIN ", + "insert into t values(0)", + "insert into t values(1)", + "insert into t values(2)", + "COMMIT", + ] + cx = sqlite.connect(":memory:") + with self.check_stmt_trace(cx, expected): + with cx: + cx.execute("create table t(t)") + cx.executemany("insert into t values(?)", ((v,) for v in range(3))) + def suite(): tests = [ diff --git a/Misc/NEWS.d/next/Library/2021-09-08-16-21-03.bpo-45138.yghUrK.rst b/Misc/NEWS.d/next/Library/2021-09-08-16-21-03.bpo-45138.yghUrK.rst new file mode 100644 index 00000000000000..906ed4c4db43c8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-09-08-16-21-03.bpo-45138.yghUrK.rst @@ -0,0 +1,3 @@ +Fix a regression in the :mod:`sqlite3` trace callback where bound parameters +were not expanded in the passed statement string. The regression was introduced +in Python 3.10 by :issue:`40318`. Patch by Erlend E. Aasland. diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index c9c10b41398e26..68c5aee79ab15f 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1050,33 +1050,65 @@ static int _progress_handler(void* user_arg) * may change in future releases. Callback implementations should return zero * to ensure future compatibility. */ -static int _trace_callback(unsigned int type, void* user_arg, void* prepared_statement, void* statement_string) +static int +_trace_callback(unsigned int type, void *callable, void *stmt, void *sql) #else -static void _trace_callback(void* user_arg, const char* statement_string) +static void +_trace_callback(void *callable, const char *sql) #endif { - PyObject *py_statement = NULL; - PyObject *ret = NULL; - - PyGILState_STATE gilstate; - #ifdef HAVE_TRACE_V2 if (type != SQLITE_TRACE_STMT) { return 0; } #endif - gilstate = PyGILState_Ensure(); - py_statement = PyUnicode_DecodeUTF8(statement_string, - strlen(statement_string), "replace"); + PyGILState_STATE gilstate = PyGILState_Ensure(); + + PyObject *py_statement = NULL; +#ifdef HAVE_TRACE_V2 + const char *expanded_sql = sqlite3_expanded_sql((sqlite3_stmt *)stmt); + if (expanded_sql == NULL) { + sqlite3 *db = sqlite3_db_handle((sqlite3_stmt *)stmt); + if (sqlite3_errcode(db) == SQLITE_NOMEM) { + (void)PyErr_NoMemory(); + goto exit; + } + + PyErr_SetString(pysqlite_DataError, + "Expanded SQL string exceeds the maximum string length"); + if (_pysqlite_enable_callback_tracebacks) { + PyErr_Print(); + } else { + PyErr_Clear(); + } + + // Fall back to unexpanded sql + py_statement = PyUnicode_FromString((const char *)sql); + } + else { + py_statement = PyUnicode_FromString(expanded_sql); + sqlite3_free((void *)expanded_sql); + } +#else + if (sql == NULL) { + PyErr_SetString(pysqlite_DataError, + "Expanded SQL string exceeds the maximum string length"); + if (_pysqlite_enable_callback_tracebacks) { + PyErr_Print(); + } else { + PyErr_Clear(); + } + goto exit; + } + py_statement = PyUnicode_FromString(sql); +#endif if (py_statement) { - ret = PyObject_CallOneArg((PyObject*)user_arg, py_statement); + PyObject *ret = PyObject_CallOneArg((PyObject *)callable, py_statement); Py_DECREF(py_statement); + Py_XDECREF(ret); } - - if (ret) { - Py_DECREF(ret); - } else { + if (PyErr_Occurred()) { if (_pysqlite_enable_callback_tracebacks) { PyErr_Print(); } else { @@ -1084,6 +1116,7 @@ static void _trace_callback(void* user_arg, const char* statement_string) } } +exit: PyGILState_Release(gilstate); #ifdef HAVE_TRACE_V2 return 0; From 0e9927b6b008ff7537600cec4f91169a006d0c9d Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 2 May 2022 09:37:10 -0700 Subject: [PATCH 125/237] gh-92082: contextlib docs: Change aclosing from a class to a function for consistency (GH-92155) Signed-off-by: prwatson (cherry picked from commit 958f21c5cdb3bbbd16fec87164785cff3dacce96) Co-authored-by: Thaddeus1499 <104600742+Thaddeus1499@users.noreply.github.com> --- Doc/library/contextlib.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst index 0fe3206540e80d..7c0b8314079683 100644 --- a/Doc/library/contextlib.rst +++ b/Doc/library/contextlib.rst @@ -181,7 +181,7 @@ Functions and classes provided: ``page.close()`` will be called when the :keyword:`with` block is exited. -.. class:: aclosing(thing) +.. function:: aclosing(thing) Return an async context manager that calls the ``aclose()`` method of *thing* upon completion of the block. This is basically equivalent to:: From 864058ba86d93eee9b6ed10b93bd8839a6131e44 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 2 May 2022 10:24:49 -0700 Subject: [PATCH 126/237] [3.10] Fix typo in Programming FAQ (GH-92083) (GH-92148) I believe the word "with" was missing here. (cherry picked from commit 2a7efa324274a54fe0e5480cae1438d8294b9ec3) Co-authored-by: Matt Harding --- Doc/faq/programming.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index a1adf851bdded7..a1701bd4184bb4 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -78,7 +78,7 @@ set of modules required by a program and bind these modules together with a Python binary to produce a single executable. One is to use the freeze tool, which is included in the Python source tree as -``Tools/freeze``. It converts Python byte code to C arrays; a C compiler you can +``Tools/freeze``. It converts Python byte code to C arrays; with a C compiler you can embed all your modules into a new program, which is then linked with the standard Python modules. From bab4d0bb1695ec8e4d89efe14c843c5080d46735 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 2 May 2022 10:34:59 -0700 Subject: [PATCH 127/237] gh-91783: Document security considerations for shutil.unpack_archive (GH-91844) (cherry picked from commit 4b297a9ffd4a1d420c1a8016f4ed2c7f1d298469) Co-authored-by: Sam Ezeh --- Doc/library/shutil.rst | 8 +++++++- .../2022-04-23-00-22-54.gh-issue-91783.N09dRR.rst | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Documentation/2022-04-23-00-22-54.gh-issue-91783.N09dRR.rst diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 403df45b3966ad..193c01006171e2 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -630,10 +630,16 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. .. audit-event:: shutil.unpack_archive filename,extract_dir,format shutil.unpack_archive + .. warning:: + + Never extract archives from untrusted sources without prior inspection. + It is possible that files are created outside of the path specified in + the *extract_dir* argument, e.g. members that have absolute filenames + starting with "/" or filenames with two dots "..". + .. versionchanged:: 3.7 Accepts a :term:`path-like object` for *filename* and *extract_dir*. - .. function:: register_unpack_format(name, extensions, function[, extra_args[, description]]) Registers an unpack format. *name* is the name of the format and diff --git a/Misc/NEWS.d/next/Documentation/2022-04-23-00-22-54.gh-issue-91783.N09dRR.rst b/Misc/NEWS.d/next/Documentation/2022-04-23-00-22-54.gh-issue-91783.N09dRR.rst new file mode 100644 index 00000000000000..4d6be37402079c --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-04-23-00-22-54.gh-issue-91783.N09dRR.rst @@ -0,0 +1,2 @@ +Document security issues concerning the use of the function +:meth:`shutil.unpack_archive` From c8ab1633fce42e84734179d267a1cd01e3fef323 Mon Sep 17 00:00:00 2001 From: Thaddeus1499 <104600742+Thaddeus1499@users.noreply.github.com> Date: Mon, 2 May 2022 14:21:51 -0400 Subject: [PATCH 128/237] [3.10] bpo-43504: Remove effbot urls (GH-26308) (#92161) * [3.10] Remove effbot urls (GH-26308). (cherry picked from commit e9f66aedf44ccc3be27975cfb070a44ce6a6bd13) Co-authored-by: E-Paine <63801254+E-Paine@users.noreply.github.com> --- Doc/about.rst | 5 ++--- Doc/faq/library.rst | 3 --- Doc/howto/curses.rst | 6 +----- Doc/library/xml.etree.elementtree.rst | 7 ------- Doc/library/xmlrpc.client.rst | 6 ------ Lib/xml/etree/ElementPath.py | 1 - Objects/stringlib/fastsearch.h | 3 ++- 7 files changed, 5 insertions(+), 26 deletions(-) diff --git a/Doc/about.rst b/Doc/about.rst index 3ea311fa629dd2..f0b908487b2d09 100644 --- a/Doc/about.rst +++ b/Doc/about.rst @@ -23,9 +23,8 @@ Many thanks go to: and writer of much of the content; * the `Docutils `_ project for creating reStructuredText and the Docutils suite; -* Fredrik Lundh for his `Alternative Python Reference - `_ project from which Sphinx got many good - ideas. +* Fredrik Lundh for his Alternative Python Reference project from which Sphinx + got many good ideas. Contributors to the Python Documentation diff --git a/Doc/faq/library.rst b/Doc/faq/library.rst index faca834e965455..b9e541c150dc43 100644 --- a/Doc/faq/library.rst +++ b/Doc/faq/library.rst @@ -106,9 +106,6 @@ support, pads, and mouse support. This means the module isn't compatible with operating systems that only have BSD curses, but there don't seem to be any currently maintained OSes that fall into this category. -For Windows: use `the consolelib module -`_. - Is there an equivalent to C's onexit() in Python? ------------------------------------------------- diff --git a/Doc/howto/curses.rst b/Doc/howto/curses.rst index cc4b4785b12290..c0149ffff37716 100644 --- a/Doc/howto/curses.rst +++ b/Doc/howto/curses.rst @@ -55,11 +55,7 @@ everything, though. The Windows version of Python doesn't include the :mod:`curses` module. A ported version called `UniCurses -`_ is available. You could -also try `the Console module `_ -written by Fredrik Lundh, which doesn't -use the same API as curses but provides cursor-addressable text output -and full support for mouse and keyboard input. +`_ is available. The Python curses module diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index 87f4ee347d604d..e3932bc9e659fe 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -363,13 +363,6 @@ These two approaches both output:: |--> Commander Clement -Additional resources -^^^^^^^^^^^^^^^^^^^^ - -See http://effbot.org/zone/element-index.htm for tutorials and links to other -docs. - - .. _elementtree-xpath: XPath support diff --git a/Doc/library/xmlrpc.client.rst b/Doc/library/xmlrpc.client.rst index 51279b35fd71b7..8d9db53ef1f0da 100644 --- a/Doc/library/xmlrpc.client.rst +++ b/Doc/library/xmlrpc.client.rst @@ -169,12 +169,6 @@ between conformable Python objects and XML on the wire. `XML-RPC Specification `_ The official specification. - `Unofficial XML-RPC Errata `_ - Fredrik Lundh's "unofficial errata, intended to clarify certain - details in the XML-RPC specification, as well as hint at - 'best practices' to use when designing your own XML-RPC - implementations." - .. _serverproxy-objects: ServerProxy Objects diff --git a/Lib/xml/etree/ElementPath.py b/Lib/xml/etree/ElementPath.py index a1170b572feea0..cd3c354d0813ee 100644 --- a/Lib/xml/etree/ElementPath.py +++ b/Lib/xml/etree/ElementPath.py @@ -226,7 +226,6 @@ def select(context, result): def prepare_predicate(next, token): # FIXME: replace with real parser!!! refs: - # http://effbot.org/zone/simple-iterator-parser.htm # http://javascript.crockford.com/tdop/tdop.html signature = [] predicate = [] diff --git a/Objects/stringlib/fastsearch.h b/Objects/stringlib/fastsearch.h index 6574720b609f4c..7b8be5d6492157 100644 --- a/Objects/stringlib/fastsearch.h +++ b/Objects/stringlib/fastsearch.h @@ -4,7 +4,8 @@ /* fast search/count implementation, based on a mix between boyer- moore and horspool, with a few more bells and whistles on the top. - for some more background, see: http://effbot.org/zone/stringlib.htm */ + for some more background, see: + https://web.archive.org/web/20201107074620/http://effbot.org/zone/stringlib.htm */ /* note: fastsearch may access s[n], which isn't a problem when using Python's ordinary string types, but may cause problems if you're From d851f37b886a91400642c4c845c56d585ab94ec0 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 2 May 2022 13:48:59 -0700 Subject: [PATCH 129/237] importlib docs: Update importlib.abc hierarchy (GH-31113) Fixed some inconsistencies in the text about relationships (cherry picked from commit 5f45a9d3c3de97a4eafedb60ecea224a78bae52c) Co-authored-by: David Gilbertson --- Doc/library/importlib.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 3576941efa46d9..c9fb63b75a4718 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -230,8 +230,8 @@ ABC hierarchy:: object +-- Finder (deprecated) - | +-- MetaPathFinder - | +-- PathEntryFinder + +-- MetaPathFinder + +-- PathEntryFinder +-- Loader +-- ResourceLoader --------+ +-- InspectLoader | @@ -264,8 +264,7 @@ ABC hierarchy:: .. class:: MetaPathFinder - An abstract base class representing a :term:`meta path finder`. For - compatibility, this is a subclass of :class:`Finder`. + An abstract base class representing a :term:`meta path finder`. .. versionadded:: 3.3 From f44e629a57dae2b29bf22449c915619503894b3b Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 2 May 2022 15:44:07 -0700 Subject: [PATCH 130/237] bpo-6686: Replace String with Bytes in xml.sax.handler documentation (GH-30612) (cherry picked from commit 32e4f450af3fbcc5c7e186f83ff74e2efe164136) Co-authored-by: Yassir Karroum --- Doc/library/xml.sax.handler.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/xml.sax.handler.rst b/Doc/library/xml.sax.handler.rst index 59d0d1b3b01175..719ce5ab1bcf65 100644 --- a/Doc/library/xml.sax.handler.rst +++ b/Doc/library/xml.sax.handler.rst @@ -147,7 +147,7 @@ for the feature and property names. .. data:: property_xml_string | value: ``"http://xml.org/sax/properties/xml-string"`` - | data type: String + | data type: Bytes | description: The literal string of characters that was the source for the current event. | access: read-only From c467812bc0174c12546f7bfdd4f6e445b87590c0 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 2 May 2022 15:45:22 -0700 Subject: [PATCH 131/237] bpo-46787: Fix `ProcessPoolExecutor exception` memory leak (GH-31408) (GH-31408) Do not store `ProcessPoolExecutor` work item exception traceback that prevents exception frame locals from being garbage collected. (cherry picked from commit 9c204b148fad9742ed19b3bce173073cdec79819) Co-authored-by: themylogin --- Lib/concurrent/futures/process.py | 3 +++ .../next/Library/2022-02-18-20-09-29.bpo-46787.juwWc0.rst | 1 + 2 files changed, 4 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2022-02-18-20-09-29.bpo-46787.juwWc0.rst diff --git a/Lib/concurrent/futures/process.py b/Lib/concurrent/futures/process.py index 6ee2ce626e4567..c03187de85a91c 100644 --- a/Lib/concurrent/futures/process.py +++ b/Lib/concurrent/futures/process.py @@ -126,6 +126,9 @@ def __init__(self, exc, tb): tb = traceback.format_exception(type(exc), exc, tb) tb = ''.join(tb) self.exc = exc + # Traceback object needs to be garbage-collected as its frames + # contain references to all the objects in the exception scope + self.exc.__traceback__ = None self.tb = '\n"""\n%s"""' % tb def __reduce__(self): return _rebuild_exc, (self.exc, self.tb) diff --git a/Misc/NEWS.d/next/Library/2022-02-18-20-09-29.bpo-46787.juwWc0.rst b/Misc/NEWS.d/next/Library/2022-02-18-20-09-29.bpo-46787.juwWc0.rst new file mode 100644 index 00000000000000..cf167ff48115b4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-02-18-20-09-29.bpo-46787.juwWc0.rst @@ -0,0 +1 @@ +Fix :class:`concurrent.futures.ProcessPoolExecutor` exception memory leak From 5f40cb85c22212365caf599665614473ac077143 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 2 May 2022 15:51:33 -0700 Subject: [PATCH 132/237] bpo-46586: Fix more erroneous doc links to builtins (GH-31429) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jelle Zijlstra Co-authored-by: Éric (cherry picked from commit cc6ae4f4835f9e76a34f24cd1f666c1cc0fecfa3) Co-authored-by: Meer Suri <46469858+meersuri@users.noreply.github.com> --- Doc/library/fileinput.rst | 2 +- Doc/library/urllib.request.rst | 2 +- Doc/library/zipfile.rst | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/fileinput.rst b/Doc/library/fileinput.rst index 19cf7c67754f6e..2df895a69c43dd 100644 --- a/Doc/library/fileinput.rst +++ b/Doc/library/fileinput.rst @@ -227,5 +227,5 @@ The two following opening hooks are provided by this module: Added the optional *errors* parameter. .. deprecated:: 3.10 - This function is deprecated since :func:`input` and :class:`FileInput` + This function is deprecated since :func:`fileinput.input` and :class:`FileInput` now have *encoding* and *errors* parameters. diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index 39d1a277aa6c75..63248b3d94f212 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -739,7 +739,7 @@ The following attribute and methods should only be used by classes derived from This method, if implemented, will be called by the parent :class:`OpenerDirector`. It should return a file-like object as described in - the return value of the :meth:`open` of :class:`OpenerDirector`, or ``None``. + the return value of the :meth:`~OpenerDirector.open` method of :class:`OpenerDirector`, or ``None``. It should raise :exc:`~urllib.error.URLError`, unless a truly exceptional thing happens (for example, :exc:`MemoryError` should not be mapped to :exc:`URLError`). diff --git a/Doc/library/zipfile.rst b/Doc/library/zipfile.rst index 43520b697c9d25..f6288709fec1aa 100644 --- a/Doc/library/zipfile.rst +++ b/Doc/library/zipfile.rst @@ -289,7 +289,7 @@ ZipFile Objects compressed text files in :term:`universal newlines` mode. .. versionchanged:: 3.6 - :meth:`open` can now be used to write files into the archive with the + :meth:`ZipFile.open` can now be used to write files into the archive with the ``mode='w'`` option. .. versionchanged:: 3.6 From adc06cd2d727d580cfeda1fc29b419ecce379687 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 2 May 2022 17:39:07 -0700 Subject: [PATCH 133/237] gh-92106: Add test that subscription works on arbitrary TypedDicts (GH-92176) (cherry picked from commit 81fb3548be5a18bf40a6f4505a02cc7fb72c9c34) Co-authored-by: Serhiy Storchaka --- Lib/test/test_typing.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 779e1758d51d8a..111a207dd10b3c 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -4485,6 +4485,19 @@ def test_get_type_hints(self): {'a': typing.Optional[int], 'b': int} ) + def test_non_generic_subscript(self): + # For backward compatibility, subscription works + # on arbitrary TypedDict types. + class TD(TypedDict): + a: T + A = TD[int] + self.assertEqual(A.__origin__, TD) + self.assertEqual(A.__parameters__, ()) + self.assertEqual(A.__args__, (int,)) + a = A(a = 1) + self.assertIs(type(a), dict) + self.assertEqual(a, {'a': 1}) + class IOTests(BaseTestCase): From 62ddbbcfafc98aaa4d0345bba56f7d6cd346c83f Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 3 May 2022 11:53:46 +0300 Subject: [PATCH 134/237] [3.10] gh-91583: AC: Fix regression for functions with defining_class (GH-91739) (GH-92079) Argument Clinic now generates the same efficient code as before adding the defining_class parameter. (cherry picked from commit a055dac0b45031878a8196a8735522de018491e3) --- ...2-04-20-14-26-14.gh-issue-91583.200qI0.rst | 2 + Modules/clinic/_curses_panel.c.h | 112 +++---- Modules/clinic/_dbmmodule.c.h | 17 +- Modules/clinic/_gdbmmodule.c.h | 62 +--- Modules/clinic/_lsprof.c.h | 17 +- Modules/clinic/_queuemodule.c.h | 39 ++- Modules/clinic/_sre.c.h | 294 +++++++++++++++--- Modules/clinic/_testmultiphase.c.h | 76 ++--- Modules/clinic/arraymodule.c.h | 10 +- Modules/clinic/md5module.c.h | 17 +- Modules/clinic/posixmodule.c.h | 56 +++- Modules/clinic/pyexpat.c.h | 83 ++++- Modules/clinic/sha1module.c.h | 17 +- Modules/clinic/sha256module.c.h | 17 +- Modules/clinic/sha512module.c.h | 17 +- Modules/clinic/zlibmodule.c.h | 161 ++++++---- Tools/clinic/clinic.py | 53 +++- 17 files changed, 661 insertions(+), 389 deletions(-) create mode 100644 Misc/NEWS.d/next/Tools-Demos/2022-04-20-14-26-14.gh-issue-91583.200qI0.rst diff --git a/Misc/NEWS.d/next/Tools-Demos/2022-04-20-14-26-14.gh-issue-91583.200qI0.rst b/Misc/NEWS.d/next/Tools-Demos/2022-04-20-14-26-14.gh-issue-91583.200qI0.rst new file mode 100644 index 00000000000000..bdfa71100f95ae --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2022-04-20-14-26-14.gh-issue-91583.200qI0.rst @@ -0,0 +1,2 @@ +Fix regression in the code generated by Argument Clinic for functions with +the ``defining_class`` parameter. diff --git a/Modules/clinic/_curses_panel.c.h b/Modules/clinic/_curses_panel.c.h index 45898070b1f543..e4642b58332de0 100644 --- a/Modules/clinic/_curses_panel.c.h +++ b/Modules/clinic/_curses_panel.c.h @@ -17,18 +17,11 @@ _curses_panel_panel_bottom_impl(PyCursesPanelObject *self, PyTypeObject *cls); static PyObject * _curses_panel_panel_bottom(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":bottom", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "bottom() takes no arguments"); + return NULL; } - return_value = _curses_panel_panel_bottom_impl(self, cls); - -exit: - return return_value; + return _curses_panel_panel_bottom_impl(self, cls); } PyDoc_STRVAR(_curses_panel_panel_hide__doc__, @@ -48,18 +41,11 @@ _curses_panel_panel_hide_impl(PyCursesPanelObject *self, PyTypeObject *cls); static PyObject * _curses_panel_panel_hide(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":hide", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "hide() takes no arguments"); + return NULL; } - return_value = _curses_panel_panel_hide_impl(self, cls); - -exit: - return return_value; + return _curses_panel_panel_hide_impl(self, cls); } PyDoc_STRVAR(_curses_panel_panel_show__doc__, @@ -77,18 +63,11 @@ _curses_panel_panel_show_impl(PyCursesPanelObject *self, PyTypeObject *cls); static PyObject * _curses_panel_panel_show(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":show", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "show() takes no arguments"); + return NULL; } - return_value = _curses_panel_panel_show_impl(self, cls); - -exit: - return return_value; + return _curses_panel_panel_show_impl(self, cls); } PyDoc_STRVAR(_curses_panel_panel_top__doc__, @@ -106,18 +85,11 @@ _curses_panel_panel_top_impl(PyCursesPanelObject *self, PyTypeObject *cls); static PyObject * _curses_panel_panel_top(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":top", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "top() takes no arguments"); + return NULL; } - return_value = _curses_panel_panel_top_impl(self, cls); - -exit: - return return_value; + return _curses_panel_panel_top_impl(self, cls); } PyDoc_STRVAR(_curses_panel_panel_above__doc__, @@ -192,12 +164,21 @@ _curses_panel_panel_move(PyCursesPanelObject *self, PyTypeObject *cls, PyObject { PyObject *return_value = NULL; static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {"ii:move", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "move", 0}; + PyObject *argsbuf[2]; int y; int x; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &y, &x)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + y = _PyLong_AsInt(args[0]); + if (y == -1 && PyErr_Occurred()) { + goto exit; + } + x = _PyLong_AsInt(args[1]); + if (x == -1 && PyErr_Occurred()) { goto exit; } return_value = _curses_panel_panel_move_impl(self, cls, y, x); @@ -243,13 +224,19 @@ _curses_panel_panel_replace(PyCursesPanelObject *self, PyTypeObject *cls, PyObje { PyObject *return_value = NULL; static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"O!:replace", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "replace", 0}; + PyObject *argsbuf[1]; PyCursesWindowObject *win; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &PyCursesWindow_Type, &win)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyObject_TypeCheck(args[0], &PyCursesWindow_Type)) { + _PyArg_BadArgument("replace", "argument 1", (&PyCursesWindow_Type)->tp_name, args[0]); goto exit; } + win = (PyCursesWindowObject *)args[0]; return_value = _curses_panel_panel_replace_impl(self, cls, win); exit: @@ -274,13 +261,15 @@ _curses_panel_panel_set_userptr(PyCursesPanelObject *self, PyTypeObject *cls, Py { PyObject *return_value = NULL; static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"O:set_userptr", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "set_userptr", 0}; + PyObject *argsbuf[1]; PyObject *obj; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &obj)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { goto exit; } + obj = args[0]; return_value = _curses_panel_panel_set_userptr_impl(self, cls, obj); exit: @@ -303,18 +292,11 @@ _curses_panel_panel_userptr_impl(PyCursesPanelObject *self, static PyObject * _curses_panel_panel_userptr(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":userptr", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "userptr() takes no arguments"); + return NULL; } - return_value = _curses_panel_panel_userptr_impl(self, cls); - -exit: - return return_value; + return _curses_panel_panel_userptr_impl(self, cls); } PyDoc_STRVAR(_curses_panel_bottom_panel__doc__, @@ -401,4 +383,4 @@ _curses_panel_update_panels(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _curses_panel_update_panels_impl(module); } -/*[clinic end generated code: output=3081ef24e5560cb0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c552457e8067bb0a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_dbmmodule.c.h b/Modules/clinic/_dbmmodule.c.h index af288c2586a10b..beb26f612026b8 100644 --- a/Modules/clinic/_dbmmodule.c.h +++ b/Modules/clinic/_dbmmodule.c.h @@ -35,18 +35,11 @@ _dbm_dbm_keys_impl(dbmobject *self, PyTypeObject *cls); static PyObject * _dbm_dbm_keys(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":keys", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "keys() takes no arguments"); + return NULL; } - return_value = _dbm_dbm_keys_impl(self, cls); - -exit: - return return_value; + return _dbm_dbm_keys_impl(self, cls); } PyDoc_STRVAR(_dbm_dbm_get__doc__, @@ -187,4 +180,4 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=6947b1115df66f7c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a4599b89ce338b08 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_gdbmmodule.c.h b/Modules/clinic/_gdbmmodule.c.h index ea4ee7df001c18..630cb499ae14fe 100644 --- a/Modules/clinic/_gdbmmodule.c.h +++ b/Modules/clinic/_gdbmmodule.c.h @@ -104,18 +104,11 @@ _gdbm_gdbm_keys_impl(gdbmobject *self, PyTypeObject *cls); static PyObject * _gdbm_gdbm_keys(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":keys", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "keys() takes no arguments"); + return NULL; } - return_value = _gdbm_gdbm_keys_impl(self, cls); - -exit: - return return_value; + return _gdbm_gdbm_keys_impl(self, cls); } PyDoc_STRVAR(_gdbm_gdbm_firstkey__doc__, @@ -137,18 +130,11 @@ _gdbm_gdbm_firstkey_impl(gdbmobject *self, PyTypeObject *cls); static PyObject * _gdbm_gdbm_firstkey(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":firstkey", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "firstkey() takes no arguments"); + return NULL; } - return_value = _gdbm_gdbm_firstkey_impl(self, cls); - -exit: - return return_value; + return _gdbm_gdbm_firstkey_impl(self, cls); } PyDoc_STRVAR(_gdbm_gdbm_nextkey__doc__, @@ -212,18 +198,11 @@ _gdbm_gdbm_reorganize_impl(gdbmobject *self, PyTypeObject *cls); static PyObject * _gdbm_gdbm_reorganize(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":reorganize", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "reorganize() takes no arguments"); + return NULL; } - return_value = _gdbm_gdbm_reorganize_impl(self, cls); - -exit: - return return_value; + return _gdbm_gdbm_reorganize_impl(self, cls); } PyDoc_STRVAR(_gdbm_gdbm_sync__doc__, @@ -244,18 +223,11 @@ _gdbm_gdbm_sync_impl(gdbmobject *self, PyTypeObject *cls); static PyObject * _gdbm_gdbm_sync(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":sync", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "sync() takes no arguments"); + return NULL; } - return_value = _gdbm_gdbm_sync_impl(self, cls); - -exit: - return return_value; + return _gdbm_gdbm_sync_impl(self, cls); } PyDoc_STRVAR(dbmopen__doc__, @@ -340,4 +312,4 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=3b88446433e43d96 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=125f5bc685304744 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_lsprof.c.h b/Modules/clinic/_lsprof.c.h index 5d9c209eab8563..b0adb746974ab3 100644 --- a/Modules/clinic/_lsprof.c.h +++ b/Modules/clinic/_lsprof.c.h @@ -39,17 +39,10 @@ _lsprof_Profiler_getstats_impl(ProfilerObject *self, PyTypeObject *cls); static PyObject * _lsprof_Profiler_getstats(ProfilerObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":getstats", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "getstats() takes no arguments"); + return NULL; } - return_value = _lsprof_Profiler_getstats_impl(self, cls); - -exit: - return return_value; + return _lsprof_Profiler_getstats_impl(self, cls); } -/*[clinic end generated code: output=b4727cfebecdd22d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=57c7b6b0b8666429 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_queuemodule.c.h b/Modules/clinic/_queuemodule.c.h index 8741f7d9aff881..29e4c60cfa7558 100644 --- a/Modules/clinic/_queuemodule.c.h +++ b/Modules/clinic/_queuemodule.c.h @@ -144,14 +144,30 @@ _queue_SimpleQueue_get(simplequeueobject *self, PyTypeObject *cls, PyObject *con { PyObject *return_value = NULL; static const char * const _keywords[] = {"block", "timeout", NULL}; - static _PyArg_Parser _parser = {"|pO:get", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "get", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int block = 1; PyObject *timeout = Py_None; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &block, &timeout)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { goto exit; } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + block = PyObject_IsTrue(args[0]); + if (block < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + timeout = args[1]; +skip_optional_pos: return_value = _queue_SimpleQueue_get_impl(self, cls, block, timeout); exit: @@ -177,18 +193,11 @@ _queue_SimpleQueue_get_nowait_impl(simplequeueobject *self, static PyObject * _queue_SimpleQueue_get_nowait(simplequeueobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":get_nowait", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "get_nowait() takes no arguments"); + return NULL; } - return_value = _queue_SimpleQueue_get_nowait_impl(self, cls); - -exit: - return return_value; + return _queue_SimpleQueue_get_nowait_impl(self, cls); } PyDoc_STRVAR(_queue_SimpleQueue_empty__doc__, @@ -246,4 +255,4 @@ _queue_SimpleQueue_qsize(simplequeueobject *self, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=ce56b46fac150909 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a9d567e8a64e6170 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_sre.c.h b/Modules/clinic/_sre.c.h index 72d772c289ae8b..d60827db24b065 100644 --- a/Modules/clinic/_sre.c.h +++ b/Modules/clinic/_sre.c.h @@ -176,15 +176,51 @@ _sre_SRE_Pattern_match(PatternObject *self, PyTypeObject *cls, PyObject *const * { PyObject *return_value = NULL; static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {"O|nn:match", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "match", 0}; + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &string, &pos, &endpos)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { goto exit; } + string = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + pos = ival; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[2]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + endpos = ival; + } +skip_optional_pos: return_value = _sre_SRE_Pattern_match_impl(self, cls, string, pos, endpos); exit: @@ -210,15 +246,51 @@ _sre_SRE_Pattern_fullmatch(PatternObject *self, PyTypeObject *cls, PyObject *con { PyObject *return_value = NULL; static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {"O|nn:fullmatch", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "fullmatch", 0}; + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &string, &pos, &endpos)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { goto exit; } + string = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + pos = ival; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[2]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + endpos = ival; + } +skip_optional_pos: return_value = _sre_SRE_Pattern_fullmatch_impl(self, cls, string, pos, endpos); exit: @@ -246,15 +318,51 @@ _sre_SRE_Pattern_search(PatternObject *self, PyTypeObject *cls, PyObject *const { PyObject *return_value = NULL; static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {"O|nn:search", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "search", 0}; + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &string, &pos, &endpos)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { goto exit; } + string = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + pos = ival; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[2]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + endpos = ival; + } +skip_optional_pos: return_value = _sre_SRE_Pattern_search_impl(self, cls, string, pos, endpos); exit: @@ -351,15 +459,51 @@ _sre_SRE_Pattern_finditer(PatternObject *self, PyTypeObject *cls, PyObject *cons { PyObject *return_value = NULL; static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {"O|nn:finditer", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "finditer", 0}; + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &string, &pos, &endpos)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { goto exit; } + string = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + pos = ival; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[2]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + endpos = ival; + } +skip_optional_pos: return_value = _sre_SRE_Pattern_finditer_impl(self, cls, string, pos, endpos); exit: @@ -384,15 +528,51 @@ _sre_SRE_Pattern_scanner(PatternObject *self, PyTypeObject *cls, PyObject *const { PyObject *return_value = NULL; static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {"O|nn:scanner", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "scanner", 0}; + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &string, &pos, &endpos)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { goto exit; } + string = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + pos = ival; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[2]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + endpos = ival; + } +skip_optional_pos: return_value = _sre_SRE_Pattern_scanner_impl(self, cls, string, pos, endpos); exit: @@ -468,15 +648,35 @@ _sre_SRE_Pattern_sub(PatternObject *self, PyTypeObject *cls, PyObject *const *ar { PyObject *return_value = NULL; static const char * const _keywords[] = {"repl", "string", "count", NULL}; - static _PyArg_Parser _parser = {"OO|n:sub", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "sub", 0}; + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *repl; PyObject *string; Py_ssize_t count = 0; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &repl, &string, &count)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); + if (!args) { goto exit; } + repl = args[0]; + string = args[1]; + if (!noptargs) { + goto skip_optional_pos; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[2]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + count = ival; + } +skip_optional_pos: return_value = _sre_SRE_Pattern_sub_impl(self, cls, repl, string, count); exit: @@ -502,15 +702,35 @@ _sre_SRE_Pattern_subn(PatternObject *self, PyTypeObject *cls, PyObject *const *a { PyObject *return_value = NULL; static const char * const _keywords[] = {"repl", "string", "count", NULL}; - static _PyArg_Parser _parser = {"OO|n:subn", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "subn", 0}; + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *repl; PyObject *string; Py_ssize_t count = 0; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &repl, &string, &count)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); + if (!args) { goto exit; } + repl = args[0]; + string = args[1]; + if (!noptargs) { + goto skip_optional_pos; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[2]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + count = ival; + } +skip_optional_pos: return_value = _sre_SRE_Pattern_subn_impl(self, cls, repl, string, count); exit: @@ -869,18 +1089,11 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self, PyTypeObject *cls); static PyObject * _sre_SRE_Scanner_match(ScannerObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":match", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "match() takes no arguments"); + return NULL; } - return_value = _sre_SRE_Scanner_match_impl(self, cls); - -exit: - return return_value; + return _sre_SRE_Scanner_match_impl(self, cls); } PyDoc_STRVAR(_sre_SRE_Scanner_search__doc__, @@ -897,17 +1110,10 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self, PyTypeObject *cls); static PyObject * _sre_SRE_Scanner_search(ScannerObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":search", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "search() takes no arguments"); + return NULL; } - return_value = _sre_SRE_Scanner_search_impl(self, cls); - -exit: - return return_value; + return _sre_SRE_Scanner_search_impl(self, cls); } -/*[clinic end generated code: output=518f7bb775c1184f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ead5eb818b7771f8 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_testmultiphase.c.h b/Modules/clinic/_testmultiphase.c.h index 17c28d54ce575a..26212d86dd0f87 100644 --- a/Modules/clinic/_testmultiphase.c.h +++ b/Modules/clinic/_testmultiphase.c.h @@ -21,18 +21,11 @@ _testmultiphase_StateAccessType_get_defining_module_impl(StateAccessTypeObject * static PyObject * _testmultiphase_StateAccessType_get_defining_module(StateAccessTypeObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":get_defining_module", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "get_defining_module() takes no arguments"); + return NULL; } - return_value = _testmultiphase_StateAccessType_get_defining_module_impl(self, cls); - -exit: - return return_value; + return _testmultiphase_StateAccessType_get_defining_module_impl(self, cls); } PyDoc_STRVAR(_testmultiphase_StateAccessType_getmodulebydef_bad_def__doc__, @@ -51,18 +44,11 @@ _testmultiphase_StateAccessType_getmodulebydef_bad_def_impl(StateAccessTypeObjec static PyObject * _testmultiphase_StateAccessType_getmodulebydef_bad_def(StateAccessTypeObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":getmodulebydef_bad_def", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "getmodulebydef_bad_def() takes no arguments"); + return NULL; } - return_value = _testmultiphase_StateAccessType_getmodulebydef_bad_def_impl(self, cls); - -exit: - return return_value; + return _testmultiphase_StateAccessType_getmodulebydef_bad_def_impl(self, cls); } PyDoc_STRVAR(_testmultiphase_StateAccessType_increment_count_clinic__doc__, @@ -88,14 +74,37 @@ _testmultiphase_StateAccessType_increment_count_clinic(StateAccessTypeObject *se { PyObject *return_value = NULL; static const char * const _keywords[] = {"n", "twice", NULL}; - static _PyArg_Parser _parser = {"|i$p:increment_count_clinic", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "increment_count_clinic", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int n = 1; int twice = 0; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &n, &twice)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { goto exit; } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + n = _PyLong_AsInt(args[0]); + if (n == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + twice = PyObject_IsTrue(args[1]); + if (twice < 0) { + goto exit; + } +skip_optional_kwonly: return_value = _testmultiphase_StateAccessType_increment_count_clinic_impl(self, cls, n, twice); exit: @@ -118,17 +127,10 @@ _testmultiphase_StateAccessType_get_count_impl(StateAccessTypeObject *self, static PyObject * _testmultiphase_StateAccessType_get_count(StateAccessTypeObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":get_count", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "get_count() takes no arguments"); + return NULL; } - return_value = _testmultiphase_StateAccessType_get_count_impl(self, cls); - -exit: - return return_value; + return _testmultiphase_StateAccessType_get_count_impl(self, cls); } -/*[clinic end generated code: output=eb1b8c2ee6290be3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ec5029d1275cbf94 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/arraymodule.c.h b/Modules/clinic/arraymodule.c.h index c46cc738de91b7..ce98e411f0fe40 100644 --- a/Modules/clinic/arraymodule.c.h +++ b/Modules/clinic/arraymodule.c.h @@ -155,13 +155,15 @@ array_array_extend(arrayobject *self, PyTypeObject *cls, PyObject *const *args, { PyObject *return_value = NULL; static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"O:extend", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "extend", 0}; + PyObject *argsbuf[1]; PyObject *bb; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &bb)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { goto exit; } + bb = args[0]; return_value = array_array_extend_impl(self, cls, bb); exit: @@ -572,4 +574,4 @@ PyDoc_STRVAR(array_arrayiterator___setstate____doc__, #define ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF \ {"__setstate__", (PyCFunction)array_arrayiterator___setstate__, METH_O, array_arrayiterator___setstate____doc__}, -/*[clinic end generated code: output=f130a994f98f1227 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=eb727e087d64f017 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/md5module.c.h b/Modules/clinic/md5module.c.h index 4762f2800d4b82..0ff09b0050a562 100644 --- a/Modules/clinic/md5module.c.h +++ b/Modules/clinic/md5module.c.h @@ -17,18 +17,11 @@ MD5Type_copy_impl(MD5object *self, PyTypeObject *cls); static PyObject * MD5Type_copy(MD5object *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":copy", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); + return NULL; } - return_value = MD5Type_copy_impl(self, cls); - -exit: - return return_value; + return MD5Type_copy_impl(self, cls); } PyDoc_STRVAR(MD5Type_digest__doc__, @@ -126,4 +119,4 @@ _md5_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw exit: return return_value; } -/*[clinic end generated code: output=53ff7f22dbaaea36 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3061297a669c645c input=a9049054013a1b77]*/ diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 7921c222b90091..742acb8e6c07e3 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -8254,12 +8254,10 @@ static PyObject * os_DirEntry_is_symlink(DirEntry *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":is_symlink", _keywords, 0}; int _return_value; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { + if (nargs) { + PyErr_SetString(PyExc_TypeError, "is_symlink() takes no arguments"); goto exit; } _return_value = os_DirEntry_is_symlink_impl(self, defining_class); @@ -8290,13 +8288,23 @@ os_DirEntry_stat(DirEntry *self, PyTypeObject *defining_class, PyObject *const * { PyObject *return_value = NULL; static const char * const _keywords[] = {"follow_symlinks", NULL}; - static _PyArg_Parser _parser = {"|$p:stat", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "stat", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int follow_symlinks = 1; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &follow_symlinks)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); + if (!args) { goto exit; } + if (!noptargs) { + goto skip_optional_kwonly; + } + follow_symlinks = PyObject_IsTrue(args[0]); + if (follow_symlinks < 0) { + goto exit; + } +skip_optional_kwonly: return_value = os_DirEntry_stat_impl(self, defining_class, follow_symlinks); exit: @@ -8321,14 +8329,24 @@ os_DirEntry_is_dir(DirEntry *self, PyTypeObject *defining_class, PyObject *const { PyObject *return_value = NULL; static const char * const _keywords[] = {"follow_symlinks", NULL}; - static _PyArg_Parser _parser = {"|$p:is_dir", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "is_dir", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int follow_symlinks = 1; int _return_value; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &follow_symlinks)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); + if (!args) { goto exit; } + if (!noptargs) { + goto skip_optional_kwonly; + } + follow_symlinks = PyObject_IsTrue(args[0]); + if (follow_symlinks < 0) { + goto exit; + } +skip_optional_kwonly: _return_value = os_DirEntry_is_dir_impl(self, defining_class, follow_symlinks); if ((_return_value == -1) && PyErr_Occurred()) { goto exit; @@ -8357,14 +8375,24 @@ os_DirEntry_is_file(DirEntry *self, PyTypeObject *defining_class, PyObject *cons { PyObject *return_value = NULL; static const char * const _keywords[] = {"follow_symlinks", NULL}; - static _PyArg_Parser _parser = {"|$p:is_file", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "is_file", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int follow_symlinks = 1; int _return_value; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &follow_symlinks)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); + if (!args) { goto exit; } + if (!noptargs) { + goto skip_optional_kwonly; + } + follow_symlinks = PyObject_IsTrue(args[0]); + if (follow_symlinks < 0) { + goto exit; + } +skip_optional_kwonly: _return_value = os_DirEntry_is_file_impl(self, defining_class, follow_symlinks); if ((_return_value == -1) && PyErr_Occurred()) { goto exit; @@ -9263,4 +9291,4 @@ os_waitstatus_to_exitcode(PyObject *module, PyObject *const *args, Py_ssize_t na #ifndef OS_WAITSTATUS_TO_EXITCODE_METHODDEF #define OS_WAITSTATUS_TO_EXITCODE_METHODDEF #endif /* !defined(OS_WAITSTATUS_TO_EXITCODE_METHODDEF) */ -/*[clinic end generated code: output=65a85d7d3f2c487e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=debefcf43738ec66 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/pyexpat.c.h b/Modules/clinic/pyexpat.c.h index 7c56d6a8b25910..bee2ee66950a5a 100644 --- a/Modules/clinic/pyexpat.c.h +++ b/Modules/clinic/pyexpat.c.h @@ -22,14 +22,24 @@ pyexpat_xmlparser_Parse(xmlparseobject *self, PyTypeObject *cls, PyObject *const { PyObject *return_value = NULL; static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {"O|i:Parse", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "Parse", 0}; + PyObject *argsbuf[2]; PyObject *data; int isfinal = 0; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &data, &isfinal)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + data = args[0]; + if (nargs < 2) { + goto skip_optional_posonly; + } + isfinal = _PyLong_AsInt(args[1]); + if (isfinal == -1 && PyErr_Occurred()) { goto exit; } +skip_optional_posonly: return_value = pyexpat_xmlparser_Parse_impl(self, cls, data, isfinal); exit: @@ -54,13 +64,15 @@ pyexpat_xmlparser_ParseFile(xmlparseobject *self, PyTypeObject *cls, PyObject *c { PyObject *return_value = NULL; static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"O:ParseFile", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "ParseFile", 0}; + PyObject *argsbuf[1]; PyObject *file; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &file)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { goto exit; } + file = args[0]; return_value = pyexpat_xmlparser_ParseFile_impl(self, cls, file); exit: @@ -164,14 +176,50 @@ pyexpat_xmlparser_ExternalEntityParserCreate(xmlparseobject *self, PyTypeObject { PyObject *return_value = NULL; static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {"z|s:ExternalEntityParserCreate", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "ExternalEntityParserCreate", 0}; + PyObject *argsbuf[2]; const char *context; const char *encoding = NULL; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &context, &encoding)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (args[0] == Py_None) { + context = NULL; + } + else if (PyUnicode_Check(args[0])) { + Py_ssize_t context_length; + context = PyUnicode_AsUTF8AndSize(args[0], &context_length); + if (context == NULL) { + goto exit; + } + if (strlen(context) != (size_t)context_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("ExternalEntityParserCreate", "argument 1", "str or None", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional_posonly; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("ExternalEntityParserCreate", "argument 2", "str", args[1]); goto exit; } + Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(args[1], &encoding_length); + if (encoding == NULL) { + goto exit; + } + if (strlen(encoding) != (size_t)encoding_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } +skip_optional_posonly: return_value = pyexpat_xmlparser_ExternalEntityParserCreate_impl(self, cls, context, encoding); exit: @@ -235,13 +283,22 @@ pyexpat_xmlparser_UseForeignDTD(xmlparseobject *self, PyTypeObject *cls, PyObjec { PyObject *return_value = NULL; static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"|p:UseForeignDTD", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "UseForeignDTD", 0}; + PyObject *argsbuf[1]; int flag = 1; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &flag)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (nargs < 1) { + goto skip_optional_posonly; + } + flag = PyObject_IsTrue(args[0]); + if (flag < 0) { goto exit; } +skip_optional_posonly: return_value = pyexpat_xmlparser_UseForeignDTD_impl(self, cls, flag); exit: @@ -368,4 +425,4 @@ pyexpat_ErrorString(PyObject *module, PyObject *arg) #ifndef PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF #define PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF #endif /* !defined(PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF) */ -/*[clinic end generated code: output=612b9d6a17a679a7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5d60049d385d5d56 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha1module.c.h b/Modules/clinic/sha1module.c.h index 3a3ab58c1233cf..d9a2e150f6d417 100644 --- a/Modules/clinic/sha1module.c.h +++ b/Modules/clinic/sha1module.c.h @@ -17,18 +17,11 @@ SHA1Type_copy_impl(SHA1object *self, PyTypeObject *cls); static PyObject * SHA1Type_copy(SHA1object *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":copy", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); + return NULL; } - return_value = SHA1Type_copy_impl(self, cls); - -exit: - return return_value; + return SHA1Type_copy_impl(self, cls); } PyDoc_STRVAR(SHA1Type_digest__doc__, @@ -126,4 +119,4 @@ _sha1_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * exit: return return_value; } -/*[clinic end generated code: output=abf1ab2545cea5a2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=93ced3c8f8fa4f21 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha256module.c.h b/Modules/clinic/sha256module.c.h index 89205c4f14f4e4..619fab1a6fe2fb 100644 --- a/Modules/clinic/sha256module.c.h +++ b/Modules/clinic/sha256module.c.h @@ -17,18 +17,11 @@ SHA256Type_copy_impl(SHAobject *self, PyTypeObject *cls); static PyObject * SHA256Type_copy(SHAobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":copy", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); + return NULL; } - return_value = SHA256Type_copy_impl(self, cls); - -exit: - return return_value; + return SHA256Type_copy_impl(self, cls); } PyDoc_STRVAR(SHA256Type_digest__doc__, @@ -177,4 +170,4 @@ _sha256_sha224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje exit: return return_value; } -/*[clinic end generated code: output=b7283f75c9d08f30 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4f9fe3ca546b0c58 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha512module.c.h b/Modules/clinic/sha512module.c.h index f1192d74f9a1ab..fada35eff22614 100644 --- a/Modules/clinic/sha512module.c.h +++ b/Modules/clinic/sha512module.c.h @@ -17,18 +17,11 @@ SHA512Type_copy_impl(SHAobject *self, PyTypeObject *cls); static PyObject * SHA512Type_copy(SHAobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":copy", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); + return NULL; } - return_value = SHA512Type_copy_impl(self, cls); - -exit: - return return_value; + return SHA512Type_copy_impl(self, cls); } PyDoc_STRVAR(SHA512Type_digest__doc__, @@ -177,4 +170,4 @@ _sha512_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje exit: return return_value; } -/*[clinic end generated code: output=9ff9f11937fabf35 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=26d2fe27b9673ac2 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h index 14e955db64e729..43948398590632 100644 --- a/Modules/clinic/zlibmodule.c.h +++ b/Modules/clinic/zlibmodule.c.h @@ -340,11 +340,19 @@ zlib_Compress_compress(compobject *self, PyTypeObject *cls, PyObject *const *arg { PyObject *return_value = NULL; static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"y*:compress", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "compress", 0}; + PyObject *argsbuf[1]; Py_buffer data = {NULL, NULL}; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &data)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("compress", "argument 1", "contiguous buffer", args[0]); goto exit; } return_value = zlib_Compress_compress_impl(self, cls, &data); @@ -387,14 +395,39 @@ zlib_Decompress_decompress(compobject *self, PyTypeObject *cls, PyObject *const { PyObject *return_value = NULL; static const char * const _keywords[] = {"", "max_length", NULL}; - static _PyArg_Parser _parser = {"y*|n:decompress", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "decompress", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; Py_ssize_t max_length = 0; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &data, &max_length)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("decompress", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + max_length = ival; + } +skip_optional_pos: return_value = zlib_Decompress_decompress_impl(self, cls, &data, max_length); exit: @@ -429,13 +462,22 @@ zlib_Compress_flush(compobject *self, PyTypeObject *cls, PyObject *const *args, { PyObject *return_value = NULL; static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"|i:flush", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "flush", 0}; + PyObject *argsbuf[1]; int mode = Z_FINISH; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &mode)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (nargs < 1) { + goto skip_optional_posonly; + } + mode = _PyLong_AsInt(args[0]); + if (mode == -1 && PyErr_Occurred()) { goto exit; } +skip_optional_posonly: return_value = zlib_Compress_flush_impl(self, cls, mode); exit: @@ -459,18 +501,11 @@ zlib_Compress_copy_impl(compobject *self, PyTypeObject *cls); static PyObject * zlib_Compress_copy(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":copy", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); + return NULL; } - return_value = zlib_Compress_copy_impl(self, cls); - -exit: - return return_value; + return zlib_Compress_copy_impl(self, cls); } #endif /* defined(HAVE_ZLIB_COPY) */ @@ -491,18 +526,11 @@ zlib_Compress___copy___impl(compobject *self, PyTypeObject *cls); static PyObject * zlib_Compress___copy__(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":__copy__", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "__copy__() takes no arguments"); + return NULL; } - return_value = zlib_Compress___copy___impl(self, cls); - -exit: - return return_value; + return zlib_Compress___copy___impl(self, cls); } #endif /* defined(HAVE_ZLIB_COPY) */ @@ -526,13 +554,15 @@ zlib_Compress___deepcopy__(compobject *self, PyTypeObject *cls, PyObject *const { PyObject *return_value = NULL; static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"O:__deepcopy__", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "__deepcopy__", 0}; + PyObject *argsbuf[1]; PyObject *memo; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &memo)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { goto exit; } + memo = args[0]; return_value = zlib_Compress___deepcopy___impl(self, cls, memo); exit: @@ -558,18 +588,11 @@ zlib_Decompress_copy_impl(compobject *self, PyTypeObject *cls); static PyObject * zlib_Decompress_copy(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":copy", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); + return NULL; } - return_value = zlib_Decompress_copy_impl(self, cls); - -exit: - return return_value; + return zlib_Decompress_copy_impl(self, cls); } #endif /* defined(HAVE_ZLIB_COPY) */ @@ -590,18 +613,11 @@ zlib_Decompress___copy___impl(compobject *self, PyTypeObject *cls); static PyObject * zlib_Decompress___copy__(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":__copy__", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "__copy__() takes no arguments"); + return NULL; } - return_value = zlib_Decompress___copy___impl(self, cls); - -exit: - return return_value; + return zlib_Decompress___copy___impl(self, cls); } #endif /* defined(HAVE_ZLIB_COPY) */ @@ -625,13 +641,15 @@ zlib_Decompress___deepcopy__(compobject *self, PyTypeObject *cls, PyObject *cons { PyObject *return_value = NULL; static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"O:__deepcopy__", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "__deepcopy__", 0}; + PyObject *argsbuf[1]; PyObject *memo; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &memo)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { goto exit; } + memo = args[0]; return_value = zlib_Decompress___deepcopy___impl(self, cls, memo); exit: @@ -661,13 +679,30 @@ zlib_Decompress_flush(compobject *self, PyTypeObject *cls, PyObject *const *args { PyObject *return_value = NULL; static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"|n:flush", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "flush", 0}; + PyObject *argsbuf[1]; Py_ssize_t length = DEF_BUF_SIZE; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &length)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { goto exit; } + if (nargs < 1) { + goto skip_optional_posonly; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + length = ival; + } +skip_optional_posonly: return_value = zlib_Decompress_flush_impl(self, cls, length); exit: @@ -803,4 +838,4 @@ zlib_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) #ifndef ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF #define ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF #endif /* !defined(ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF) */ -/*[clinic end generated code: output=6736bae59fab268b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1bda0d996fb51269 input=a9049054013a1b77]*/ diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 969008ade9790f..b442c494d31d49 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -636,6 +636,10 @@ def output_templates(self, f): assert parameters assert isinstance(parameters[0].converter, self_converter) del parameters[0] + requires_defining_class = False + if parameters and isinstance(parameters[0].converter, defining_class_converter): + requires_defining_class = True + del parameters[0] converters = [p.converter for p in parameters] has_option_groups = parameters and (parameters[0].group or parameters[-1].group) @@ -657,10 +661,6 @@ def output_templates(self, f): if not p.is_optional(): min_pos = i - requires_defining_class = any( - isinstance(p.converter, defining_class_converter) - for p in parameters) - meth_o = (len(parameters) == 1 and parameters[0].is_positional_only() and not converters[0].is_optional() and @@ -763,24 +763,40 @@ def parser_body(prototype, *fields, declarations=''): return linear_format(output(), parser_declarations=declarations) if not parameters: - # no parameters, METH_NOARGS + if not requires_defining_class: + # no parameters, METH_NOARGS + flags = "METH_NOARGS" - flags = "METH_NOARGS" + parser_prototype = normalize_snippet(""" + static PyObject * + {c_basename}({self_type}{self_name}, PyObject *Py_UNUSED(ignored)) + """) + parser_code = [] - parser_prototype = normalize_snippet(""" - static PyObject * - {c_basename}({self_type}{self_name}, PyObject *Py_UNUSED(ignored)) - """) - parser_definition = parser_prototype + else: + assert not new_or_init - if default_return_converter: - parser_definition = parser_prototype + '\n' + normalize_snippet(""" - {{ - return {c_basename}_impl({impl_arguments}); + flags = "METH_METHOD|METH_FASTCALL|METH_KEYWORDS" + + parser_prototype = parser_prototype_def_class + return_error = ('return NULL;' if default_return_converter + else 'goto exit;') + parser_code = [normalize_snippet(""" + if (nargs) {{ + PyErr_SetString(PyExc_TypeError, "{name}() takes no arguments"); + %s }} - """) + """ % return_error, indent=4)] + + if default_return_converter: + parser_definition = '\n'.join([ + parser_prototype, + '{{', + *parser_code, + ' return {c_basename}_impl({impl_arguments});', + '}}']) else: - parser_definition = parser_body(parser_prototype) + parser_definition = parser_body(parser_prototype, *parser_code) elif meth_o: flags = "METH_O" @@ -939,6 +955,9 @@ def parser_body(prototype, *fields, declarations=''): add_label = None for i, p in enumerate(parameters): + if isinstance(p.converter, defining_class_converter): + raise ValueError("defining_class should be the first " + "parameter (after self)") displayname = p.get_displayname(i+1) parsearg = p.converter.parse_arg(argname_fmt % i, displayname) if parsearg is None: From 5f709bdb86261fdba3ea8e5fd529f8af9fca4f42 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 3 May 2022 05:37:17 -0700 Subject: [PATCH 135/237] bpo-46415: Use f-string for ValueError in ipaddress.ip_{address,network,interface} helper functions (GH-30642) `IPv*Network` and `IPv*Interface` constructors accept a 2-tuple of (address description, netmask) as the address parameter. When the tuple-based address is used errors are not propagated correctly through the `ipaddress.ip_*` helper because of the %-formatting now expecting several arguments: In [7]: ipaddress.ip_network(("192.168.100.0", "fooo")) ... TypeError: not all arguments converted during string formatting Compared to: In [8]: ipaddress.IPv4Network(("192.168.100.0", "foo")) ... NetmaskValueError: 'foo' is not a valid netmask Use an f-string to make sure the error is always properly formatted. Co-authored-by: Jelle Zijlstra (cherry picked from commit 52dc9c3066bcdc67a7a45d41cf158ecb1434d5f3) Co-authored-by: Thomas Cellerier --- Lib/ipaddress.py | 15 ++++++--------- Lib/test/test_ipaddress.py | 16 ++++++++++++++++ .../2022-01-17-16-53-30.bpo-46415.6wSYg-.rst | 2 ++ 3 files changed, 24 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-01-17-16-53-30.bpo-46415.6wSYg-.rst diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py index 4a6496a5da3ef8..756f1bc38c97fd 100644 --- a/Lib/ipaddress.py +++ b/Lib/ipaddress.py @@ -51,8 +51,7 @@ def ip_address(address): except (AddressValueError, NetmaskValueError): pass - raise ValueError('%r does not appear to be an IPv4 or IPv6 address' % - address) + raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 address') def ip_network(address, strict=True): @@ -81,8 +80,7 @@ def ip_network(address, strict=True): except (AddressValueError, NetmaskValueError): pass - raise ValueError('%r does not appear to be an IPv4 or IPv6 network' % - address) + raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 network') def ip_interface(address): @@ -116,8 +114,7 @@ def ip_interface(address): except (AddressValueError, NetmaskValueError): pass - raise ValueError('%r does not appear to be an IPv4 or IPv6 interface' % - address) + raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 interface') def v4_int_to_packed(address): @@ -160,7 +157,7 @@ def _split_optional_netmask(address): """Helper to split the netmask and raise AddressValueError if needed""" addr = str(address).split('/') if len(addr) > 2: - raise AddressValueError("Only one '/' permitted in %r" % address) + raise AddressValueError(f"Only one '/' permitted in {address!r}") return addr @@ -1304,7 +1301,7 @@ def __init__(self, address): # which converts into a formatted IP string. addr_str = str(address) if '/' in addr_str: - raise AddressValueError("Unexpected '/' in %r" % address) + raise AddressValueError(f"Unexpected '/' in {address!r}") self._ip = self._ip_int_from_string(addr_str) @property @@ -1913,7 +1910,7 @@ def __init__(self, address): # which converts into a formatted IP string. addr_str = str(address) if '/' in addr_str: - raise AddressValueError("Unexpected '/' in %r" % address) + raise AddressValueError(f"Unexpected '/' in {address!r}") addr_str, self._scope_id = self._split_scope_id(addr_str) self._ip = self._ip_int_from_string(addr_str) diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py index ff77bdb1bbc582..b2bb609ea8b4b3 100644 --- a/Lib/test/test_ipaddress.py +++ b/Lib/test/test_ipaddress.py @@ -1133,6 +1133,14 @@ def testIPv4Tuple(self): self.assertEqual(ipaddress.IPv4Interface((3221225985, 24)), ipaddress.IPv4Interface('192.0.2.1/24')) + # Invalid netmask + with self.assertRaises(ValueError): + ipaddress.IPv4Network(('192.0.2.1', '255.255.255.255.0')) + + # Invalid netmask using factory + with self.assertRaises(ValueError): + ipaddress.ip_network(('192.0.2.1', '255.255.255.255.0')) + # issue #16531: constructing IPv6Network from an (address, mask) tuple def testIPv6Tuple(self): # /128 @@ -1192,6 +1200,14 @@ def testIPv6Tuple(self): ipaddress.IPv6Network((ip_scoped, 96)) # strict=False and host bits set + # Invalid netmask + with self.assertRaises(ValueError): + ipaddress.IPv6Network(('2001:db8::1', '255.255.255.0')) + + # Invalid netmask using factory + with self.assertRaises(ValueError): + ipaddress.ip_network(('2001:db8::1', '255.255.255.0')) + # issue57 def testAddressIntMath(self): self.assertEqual(ipaddress.IPv4Address('1.1.1.1') + 255, diff --git a/Misc/NEWS.d/next/Library/2022-01-17-16-53-30.bpo-46415.6wSYg-.rst b/Misc/NEWS.d/next/Library/2022-01-17-16-53-30.bpo-46415.6wSYg-.rst new file mode 100644 index 00000000000000..016d6656041f91 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-01-17-16-53-30.bpo-46415.6wSYg-.rst @@ -0,0 +1,2 @@ +Fix ipaddress.ip_{address,interface,network} raising TypeError instead of +ValueError if given invalid tuple as address parameter. From 58f2d2d10aed5edbde85403c17ad2a54eb37db54 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 3 May 2022 09:24:39 -0700 Subject: [PATCH 136/237] bpo-46604: fix function name in ssl module docstring (GH-31064) The function fetch_server_certificate is replaced by get_server_certificate in the module. I reflected the change in the module docstrings. Co-authored-by: Jelle Zijlstra (cherry picked from commit feca9bbd1f6489f2b6d2783bfc22fdb96e45b69f) Co-authored-by: Kossi GLOKPOR <83467320+glk0@users.noreply.github.com> --- Lib/ssl.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Lib/ssl.py b/Lib/ssl.py index 181065d2e53bac..b09d684ed0fc6a 100644 --- a/Lib/ssl.py +++ b/Lib/ssl.py @@ -18,9 +18,10 @@ seconds past the Epoch (the time values returned from time.time()) - fetch_server_certificate (HOST, PORT) -- fetch the certificate provided - by the server running on HOST at port PORT. No - validation of the certificate is performed. + get_server_certificate (addr, ssl_version, ca_certs, timeout) -- Retrieve the + certificate from the server at the specified + address and return it as a PEM-encoded string + Integer constants: From 30681d6655f1d25fd8ca10df0e2088a17733742c Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 3 May 2022 11:18:31 -0700 Subject: [PATCH 137/237] bpo-29890: Test IPv*Interface construction with tuple argument (GH-30862) Co-authored-by: Jelle Zijlstra (cherry picked from commit b295a92c50b128e494f47c28f12b8e9eac2927ea) Co-authored-by: Humbled Drugman --- Lib/test/test_ipaddress.py | 8 ++++++++ .../next/Tests/2022-01-24-21-31-09.bpo-29890.zEG-ra.rst | 2 ++ 2 files changed, 10 insertions(+) create mode 100644 Misc/NEWS.d/next/Tests/2022-01-24-21-31-09.bpo-29890.zEG-ra.rst diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py index b2bb609ea8b4b3..f012af052322d3 100644 --- a/Lib/test/test_ipaddress.py +++ b/Lib/test/test_ipaddress.py @@ -580,6 +580,10 @@ def assertBadAddress(addr, details): assertBadAddress("1.2.3.256", re.escape("256 (> 255)")) def test_valid_netmask(self): + self.assertEqual(str(self.factory(('192.0.2.0', 24))), '192.0.2.0/24') + self.assertEqual(str(self.factory(('192.0.2.0', '24'))), '192.0.2.0/24') + self.assertEqual(str(self.factory(('192.0.2.0', '255.255.255.0'))), + '192.0.2.0/24') self.assertEqual(str(self.factory('192.0.2.0/255.255.255.0')), '192.0.2.0/24') for i in range(0, 33): @@ -740,6 +744,10 @@ def assertBadAddress(addr, details): def test_valid_netmask(self): # We only support CIDR for IPv6, because expanded netmasks are not # standard notation. + self.assertEqual(str(self.factory(('2001:db8::', 32))), + '2001:db8::/32') + self.assertEqual(str(self.factory(('2001:db8::', '32'))), + '2001:db8::/32') self.assertEqual(str(self.factory('2001:db8::/32')), '2001:db8::/32') for i in range(0, 129): # Generate and re-parse the CIDR format (trivial). diff --git a/Misc/NEWS.d/next/Tests/2022-01-24-21-31-09.bpo-29890.zEG-ra.rst b/Misc/NEWS.d/next/Tests/2022-01-24-21-31-09.bpo-29890.zEG-ra.rst new file mode 100644 index 00000000000000..38a06a2f9b6be2 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-01-24-21-31-09.bpo-29890.zEG-ra.rst @@ -0,0 +1,2 @@ +Add tests for :class:`ipaddress.IPv4Interface` and :class:`ipaddress.IPv6Interface` construction with tuple arguments. +Original patch and tests by louisom. From 666820cb4bc5e269e3110a9781278bf496dcbced Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 3 May 2022 15:24:03 -0700 Subject: [PATCH 138/237] gh-87304: Improve comments in language reference for imports (GH-92164) (cherry picked from commit ee2205b208389611e8a278ac1bc74b34f4994fd2) Co-authored-by: Robert Yang <35813883+robert861212@users.noreply.github.com> --- Doc/reference/simple_stmts.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst index 8dfc01db263f5c..d5f1e045e980cb 100644 --- a/Doc/reference/simple_stmts.rst +++ b/Doc/reference/simple_stmts.rst @@ -795,9 +795,9 @@ The :keyword:`from` form uses a slightly more complex process: Examples:: import foo # foo imported and bound locally - import foo.bar.baz # foo.bar.baz imported, foo bound locally - import foo.bar.baz as fbb # foo.bar.baz imported and bound as fbb - from foo.bar import baz # foo.bar.baz imported and bound as baz + import foo.bar.baz # foo, foo.bar, and foo.bar.baz imported, foo bound locally + import foo.bar.baz as fbb # foo, foo.bar, and foo.bar.baz imported, foo.bar.baz bound as fbb + from foo.bar import baz # foo, foo.bar, and foo.bar.baz imported, foo.bar.baz bound as baz from foo import attr # foo imported and foo.attr bound as attr .. index:: single: * (asterisk); import statement From 31d9a88ca8ecf06c410a980e08bb848101d4461a Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Tue, 3 May 2022 16:41:39 -0600 Subject: [PATCH 139/237] [3.10] Improve the typing docs (GH-92264) (#92270) Co-authored-by: Alex Waygood . (cherry picked from commit 27e366571590e9e98f61dccf69dbeaa88ee66737) Co-authored-by: Jelle Zijlstra --- Doc/library/typing.rst | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 6a160af895c064..bcf2b22b1a3c2a 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -115,7 +115,7 @@ Note that ``None`` as a type hint is a special case and is replaced by NewType ======= -Use the :class:`NewType` helper class to create distinct types:: +Use the :class:`NewType` helper to create distinct types:: from typing import NewType @@ -144,7 +144,7 @@ accidentally creating a ``UserId`` in an invalid way:: Note that these checks are enforced only by the static type checker. At runtime, the statement ``Derived = NewType('Derived', Base)`` will make ``Derived`` a -class that immediately returns whatever parameter you pass it. That means +callable that immediately returns whatever parameter you pass it. That means the expression ``Derived(some_value)`` does not create a new class or introduce much overhead beyond that of a regular function call. @@ -232,7 +232,7 @@ respectively. See :pep:`612` for more information. .. seealso:: - The documentation for :class:`ParamSpec` and :class:`Concatenate` provide + The documentation for :class:`ParamSpec` and :class:`Concatenate` provides examples of usage in ``Callable``. .. _generics: @@ -401,7 +401,7 @@ to this is that a list of types can be used to substitute a :class:`ParamSpec`:: Furthermore, a generic with only one parameter specification variable will accept parameter lists in the forms ``X[[Type1, Type2, ...]]`` and also ``X[Type1, Type2, ...]`` for aesthetic reasons. Internally, the latter is converted -to the former and are thus equivalent:: +to the former, so the following are equivalent:: >>> class X(Generic[P]): ... ... @@ -505,7 +505,7 @@ manner. Use :data:`Any` to indicate that a value is dynamically typed. Nominal vs structural subtyping =============================== -Initially :pep:`484` defined Python static type system as using +Initially :pep:`484` defined the Python static type system as using *nominal subtyping*. This means that a class ``A`` is allowed where a class ``B`` is expected if and only if ``A`` is a subclass of ``B``. @@ -756,7 +756,6 @@ These can be used as types in annotations using ``[]``, each having a unique syn def with_lock(f: Callable[Concatenate[Lock, P], R]) -> Callable[P, R]: '''A type-safe decorator which provides a lock.''' - global my_lock def inner(*args: P.args, **kwargs: P.kwargs) -> R: # Provide the lock as the first argument. return f(my_lock, *args, **kwargs) @@ -912,7 +911,7 @@ These can be used as types in annotations using ``[]``, each having a unique syn ``no_type_check`` functionality that currently exists in the ``typing`` module which completely disables typechecking annotations on a function or a class, the ``Annotated`` type allows for both static typechecking - of ``T`` (e.g., via mypy or Pyre, which can safely ignore ``x``) + of ``T`` (which can safely ignore ``x``) together with runtime access to ``x`` within a specific application. Ultimately, the responsibility of how to interpret the annotations (if @@ -1016,7 +1015,7 @@ These can be used as types in annotations using ``[]``, each having a unique syn 2. If the return value is ``True``, the type of its argument is the type inside ``TypeGuard``. - For example:: + For example:: def is_str_list(val: List[object]) -> TypeGuard[List[str]]: '''Determines whether all objects in the list are strings''' @@ -1230,11 +1229,11 @@ These are not used in annotations. They are building blocks for creating generic use a :class:`TypeVar` with bound ``Callable[..., Any]``. However this causes two problems: - 1. The type checker can't type check the ``inner`` function because - ``*args`` and ``**kwargs`` have to be typed :data:`Any`. - 2. :func:`~cast` may be required in the body of the ``add_logging`` - decorator when returning the ``inner`` function, or the static type - checker must be told to ignore the ``return inner``. + 1. The type checker can't type check the ``inner`` function because + ``*args`` and ``**kwargs`` have to be typed :data:`Any`. + 2. :func:`~cast` may be required in the body of the ``add_logging`` + decorator when returning the ``inner`` function, or the static type + checker must be told to ignore the ``return inner``. .. attribute:: args .. attribute:: kwargs @@ -1392,7 +1391,7 @@ These are not used in annotations. They are building blocks for declaring types. The resulting class has an extra attribute ``__annotations__`` giving a dict that maps the field names to the field types. (The field names are in the ``_fields`` attribute and the default values are in the - ``_field_defaults`` attribute both of which are part of the namedtuple + ``_field_defaults`` attribute, both of which are part of the :func:`~collections.namedtuple` API.) ``NamedTuple`` subclasses can also have docstrings and methods:: @@ -1467,7 +1466,7 @@ These are not used in annotations. They are building blocks for declaring types. Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str}) The functional syntax should also be used when any of the keys are not valid - :ref:`identifiers`, for example because they are keywords or contain hyphens. + :ref:`identifiers `, for example because they are keywords or contain hyphens. Example:: # raises SyntaxError @@ -1506,7 +1505,7 @@ These are not used in annotations. They are building blocks for declaring types. y: int z: int - A ``TypedDict`` cannot inherit from a non-TypedDict class, + A ``TypedDict`` cannot inherit from a non-\ ``TypedDict`` class, notably including :class:`Generic`. For example:: class X(TypedDict): @@ -1915,7 +1914,7 @@ Corresponding to other types in :mod:`collections.abc` .. class:: Hashable - An alias to :class:`collections.abc.Hashable` + An alias to :class:`collections.abc.Hashable`. .. class:: Reversible(Iterable[T_co]) @@ -1927,7 +1926,7 @@ Corresponding to other types in :mod:`collections.abc` .. class:: Sized - An alias to :class:`collections.abc.Sized` + An alias to :class:`collections.abc.Sized`. Asynchronous programming """""""""""""""""""""""" @@ -2132,7 +2131,7 @@ Functions and decorators ... class Sub(Base): def done(self) -> None: # Error reported by type checker - ... + ... @final class Leaf: @@ -2293,8 +2292,8 @@ Constant If ``from __future__ import annotations`` is used in Python 3.7 or later, annotations are not evaluated at function definition time. - Instead, they are stored as strings in ``__annotations__``, - This makes it unnecessary to use quotes around the annotation. + Instead, they are stored as strings in ``__annotations__``. + This makes it unnecessary to use quotes around the annotation (see :pep:`563`). .. versionadded:: 3.5.2 From 28eea73e7c5405ec41dda0cddae2a3ebaac908f5 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 3 May 2022 17:16:21 -0700 Subject: [PATCH 140/237] bpo-47029: Fix BrokenPipeError in multiprocessing.Queue at garbage collection and explicit close (GH-31913) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit dfb1b9da8a4becaeaed3d9cffcaac41bcaf746f4) Co-authored-by: Géry Ogam --- Lib/multiprocessing/queues.py | 23 +++++++++---------- .../2022-04-26-19-01-13.bpo-47029.qkT42X.rst | 4 ++++ 2 files changed, 15 insertions(+), 12 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-04-26-19-01-13.bpo-47029.qkT42X.rst diff --git a/Lib/multiprocessing/queues.py b/Lib/multiprocessing/queues.py index a2901814876d6c..f37f114a968871 100644 --- a/Lib/multiprocessing/queues.py +++ b/Lib/multiprocessing/queues.py @@ -139,13 +139,10 @@ def put_nowait(self, obj): def close(self): self._closed = True - try: - self._reader.close() - finally: - close = self._close - if close: - self._close = None - close() + close = self._close + if close: + self._close = None + close() def join_thread(self): debug('Queue.join_thread()') @@ -169,8 +166,9 @@ def _start_thread(self): self._thread = threading.Thread( target=Queue._feed, args=(self._buffer, self._notempty, self._send_bytes, - self._wlock, self._writer.close, self._ignore_epipe, - self._on_queue_feeder_error, self._sem), + self._wlock, self._reader.close, self._writer.close, + self._ignore_epipe, self._on_queue_feeder_error, + self._sem), name='QueueFeederThread' ) self._thread.daemon = True @@ -211,8 +209,8 @@ def _finalize_close(buffer, notempty): notempty.notify() @staticmethod - def _feed(buffer, notempty, send_bytes, writelock, close, ignore_epipe, - onerror, queue_sem): + def _feed(buffer, notempty, send_bytes, writelock, reader_close, + writer_close, ignore_epipe, onerror, queue_sem): debug('starting thread to feed data to pipe') nacquire = notempty.acquire nrelease = notempty.release @@ -238,7 +236,8 @@ def _feed(buffer, notempty, send_bytes, writelock, close, ignore_epipe, obj = bpopleft() if obj is sentinel: debug('feeder thread got sentinel -- exiting') - close() + reader_close() + writer_close() return # serialize the data before acquiring the lock diff --git a/Misc/NEWS.d/next/Library/2022-04-26-19-01-13.bpo-47029.qkT42X.rst b/Misc/NEWS.d/next/Library/2022-04-26-19-01-13.bpo-47029.qkT42X.rst new file mode 100644 index 00000000000000..cc054673338f0b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-26-19-01-13.bpo-47029.qkT42X.rst @@ -0,0 +1,4 @@ +Always close the read end of the pipe used by :class:`multiprocessing.Queue` +*after* the last write of buffered data to the write end of the pipe to avoid +:exc:`BrokenPipeError` at garbage collection and at +:meth:`multiprocessing.Queue.close` calls. Patch by Géry Ogam. From 178a238f25ab8aff7689d7a09d66dc1583ecd6cb Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 4 May 2022 03:23:29 -0700 Subject: [PATCH 141/237] gh-92036: Fix gc_fini_untrack() (GH-92037) Fix a crash in subinterpreters related to the garbage collector. When a subinterpreter is deleted, untrack all objects tracked by its GC. To prevent a crash in deallocator functions expecting objects to be tracked by the GC, leak a strong reference to these objects on purpose, so they are never deleted and their deallocator functions are not called. (cherry picked from commit 14243369b5f80613628a565c224bba7fb3fcacd8) Co-authored-by: Victor Stinner --- .../2022-04-28-23-37-30.gh-issue-92036.GZJAC9.rst | 5 +++++ Modules/gcmodule.c | 6 ++++++ 2 files changed, 11 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-04-28-23-37-30.gh-issue-92036.GZJAC9.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-04-28-23-37-30.gh-issue-92036.GZJAC9.rst b/Misc/NEWS.d/next/Core and Builtins/2022-04-28-23-37-30.gh-issue-92036.GZJAC9.rst new file mode 100644 index 00000000000000..78094c5e4fea7c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-04-28-23-37-30.gh-issue-92036.GZJAC9.rst @@ -0,0 +1,5 @@ +Fix a crash in subinterpreters related to the garbage collector. When a +subinterpreter is deleted, untrack all objects tracked by its GC. To prevent a +crash in deallocator functions expecting objects to be tracked by the GC, leak +a strong reference to these objects on purpose, so they are never deleted and +their deallocator functions are not called. Patch by Victor Stinner. diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 805a159d53d60f..43ae6fa98beb90 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -2170,6 +2170,12 @@ gc_fini_untrack(PyGC_Head *list) for (gc = GC_NEXT(list); gc != list; gc = GC_NEXT(list)) { PyObject *op = FROM_GC(gc); _PyObject_GC_UNTRACK(op); + // gh-92036: If a deallocator function expect the object to be tracked + // by the GC (ex: func_dealloc()), it can crash if called on an object + // which is no longer tracked by the GC. Leak one strong reference on + // purpose so the object is never deleted and its deallocator is not + // called. + Py_INCREF(op); } } From bb2dcf1c7996c9da3372b89c1759c94ed567b298 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 4 May 2022 17:30:54 -0700 Subject: [PATCH 142/237] gh-92223: Remove pre-Python 3.7 alternative in asyncio docs (GH-92224) (cherry picked from commit d1b2e989be2bc5128d6602e4f370d0ee6f5ac476) Co-authored-by: Sebastian Rittau --- Doc/library/asyncio-task.rst | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index efd4d1bc628ad8..dc09286e5f852d 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -20,7 +20,7 @@ Coroutines :term:`Coroutines ` declared with the async/await syntax is the preferred way of writing asyncio applications. For example, the following -snippet of code (requires Python 3.7+) prints "hello", waits 1 second, +snippet of code prints "hello", waits 1 second, and then prints "world":: >>> import asyncio @@ -259,21 +259,6 @@ Creating Tasks :exc:`RuntimeError` is raised if there is no running loop in current thread. - This function has been **added in Python 3.7**. Prior to - Python 3.7, the low-level :func:`asyncio.ensure_future` function - can be used instead:: - - async def coro(): - ... - - # In Python 3.7+ - task = asyncio.create_task(coro()) - ... - - # This works in all Python versions but is less readable - task = asyncio.ensure_future(coro()) - ... - .. important:: Save a reference to the result of this function, to avoid From 9b47252d5433894c26fc07aa87b1bd6bb4238e5e Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 5 May 2022 10:47:59 -0700 Subject: [PATCH 143/237] [3.10] gh-92118: Add test for traceback when exception is modified by (Async)ExitStack.__exit__ (GH-92339) (GH-92343) --- Lib/test/test_contextlib.py | 37 +++++++++++++++++++++++++++++++ Lib/test/test_contextlib_async.py | 7 ++++++ 2 files changed, 44 insertions(+) diff --git a/Lib/test/test_contextlib.py b/Lib/test/test_contextlib.py index fbaae2dd09fd95..68bd45d97232c7 100644 --- a/Lib/test/test_contextlib.py +++ b/Lib/test/test_contextlib.py @@ -4,6 +4,7 @@ import sys import tempfile import threading +import traceback import unittest from contextlib import * # Tests __all__ from test import support @@ -701,6 +702,38 @@ def test_exit_suppress(self): stack.push(lambda *exc: True) 1/0 + def test_exit_exception_traceback(self): + # This test captures the current behavior of ExitStack so that we know + # if we ever unintendedly change it. It is not a statement of what the + # desired behavior is (for instance, we may want to remove some of the + # internal contextlib frames). + + def raise_exc(exc): + raise exc + + try: + with self.exit_stack() as stack: + stack.callback(raise_exc, ValueError) + 1/0 + except ValueError as e: + exc = e + + self.assertIsInstance(exc, ValueError) + ve_frames = traceback.extract_tb(exc.__traceback__) + expected = \ + [('test_exit_exception_traceback', 'with self.exit_stack() as stack:')] + \ + self.callback_error_internal_frames + \ + [('_exit_wrapper', 'callback(*args, **kwds)'), + ('raise_exc', 'raise exc')] + + self.assertEqual( + [(f.name, f.line) for f in ve_frames], expected) + + self.assertIsInstance(exc.__context__, ZeroDivisionError) + zde_frames = traceback.extract_tb(exc.__context__.__traceback__) + self.assertEqual([(f.name, f.line) for f in zde_frames], + [('test_exit_exception_traceback', '1/0')]) + def test_exit_exception_chaining_reference(self): # Sanity check to make sure that ExitStack chaining matches # actual nested with statements @@ -968,6 +1001,10 @@ def first(): class TestExitStack(TestBaseExitStack, unittest.TestCase): exit_stack = ExitStack + callback_error_internal_frames = [ + ('__exit__', 'raise exc_details[1]'), + ('__exit__', 'if cb(*exc_details):'), + ] class TestRedirectStream: diff --git a/Lib/test/test_contextlib_async.py b/Lib/test/test_contextlib_async.py index 127d7500656a59..d6a34e22ac4249 100644 --- a/Lib/test/test_contextlib_async.py +++ b/Lib/test/test_contextlib_async.py @@ -412,6 +412,13 @@ def __exit__(self, *exc_details): return self.run_coroutine(self.__aexit__(*exc_details)) exit_stack = SyncAsyncExitStack + callback_error_internal_frames = [ + ('__exit__', 'return self.run_coroutine(self.__aexit__(*exc_details))'), + ('run_coroutine', 'raise exc'), + ('run_coroutine', 'raise exc'), + ('__aexit__', 'raise exc_details[1]'), + ('__aexit__', 'cb_suppress = cb(*exc_details)'), + ] def setUp(self): self.loop = asyncio.new_event_loop() From 2a2421e538f9f7ceb419074909a313ba2c46f384 Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Thu, 5 May 2022 21:46:21 +0200 Subject: [PATCH 144/237] [3.10] gh-80254: Disallow recursive usage of cursors in `sqlite3` converters (#92274) * [3.10] gh-80254: Disallow recursive usage of cursors in `sqlite3` converters (#29054) (cherry picked from commit f629dcfe835e349433e4c5099381d668e8fe69c8) Co-authored-by: Sergey Fedoseev Co-authored-by: Jelle Zijlstra * Fix ref leak in pysqlite_cursor_iternext --- Lib/sqlite3/test/regression.py | 42 ++++++++++++++++- .../2019-06-22-11-01-45.bpo-36073.ED8mB9.rst | 2 + Modules/_sqlite/cursor.c | 46 +++++++++++++------ 3 files changed, 75 insertions(+), 15 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-06-22-11-01-45.bpo-36073.ED8mB9.rst diff --git a/Lib/sqlite3/test/regression.py b/Lib/sqlite3/test/regression.py index 70d0ff9af10713..8937f9f69eb034 100644 --- a/Lib/sqlite3/test/regression.py +++ b/Lib/sqlite3/test/regression.py @@ -27,6 +27,9 @@ import functools from test import support +from unittest.mock import patch + + class RegressionTests(unittest.TestCase): def setUp(self): self.con = sqlite.connect(":memory:") @@ -415,9 +418,46 @@ def test_return_empty_bytestring(self): self.assertEqual(val, b'') +class RecursiveUseOfCursors(unittest.TestCase): + # GH-80254: sqlite3 should not segfault for recursive use of cursors. + msg = "Recursive use of cursors not allowed" + + def setUp(self): + self.con = sqlite.connect(":memory:", + detect_types=sqlite.PARSE_COLNAMES) + self.cur = self.con.cursor() + self.cur.execute("create table test(x foo)") + self.cur.executemany("insert into test(x) values (?)", + [("foo",), ("bar",)]) + + def tearDown(self): + self.cur.close() + self.con.close() + + def test_recursive_cursor_init(self): + conv = lambda x: self.cur.__init__(self.con) + with patch.dict(sqlite.converters, {"INIT": conv}): + with self.assertRaisesRegex(sqlite.ProgrammingError, self.msg): + self.cur.execute(f'select x as "x [INIT]", x from test') + + def test_recursive_cursor_close(self): + conv = lambda x: self.cur.close() + with patch.dict(sqlite.converters, {"CLOSE": conv}): + with self.assertRaisesRegex(sqlite.ProgrammingError, self.msg): + self.cur.execute(f'select x as "x [CLOSE]", x from test') + + def test_recursive_cursor_fetch(self): + conv = lambda x, l=[]: self.cur.fetchone() if l else l.append(None) + with patch.dict(sqlite.converters, {"ITER": conv}): + self.cur.execute(f'select x as "x [ITER]", x from test') + with self.assertRaisesRegex(sqlite.ProgrammingError, self.msg): + self.cur.fetchall() + + def suite(): tests = [ - RegressionTests + RegressionTests, + RecursiveUseOfCursors, ] return unittest.TestSuite( [unittest.TestLoader().loadTestsFromTestCase(t) for t in tests] diff --git a/Misc/NEWS.d/next/Library/2019-06-22-11-01-45.bpo-36073.ED8mB9.rst b/Misc/NEWS.d/next/Library/2019-06-22-11-01-45.bpo-36073.ED8mB9.rst new file mode 100644 index 00000000000000..6c214d8191601c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-22-11-01-45.bpo-36073.ED8mB9.rst @@ -0,0 +1,2 @@ +Raise :exc:`~sqlite3.ProgrammingError` instead of segfaulting on recursive +usage of cursors in :mod:`sqlite3` converters. Patch by Sergey Fedoseev. diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 85267cc9e7700c..ac80c285fe9957 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -26,6 +26,17 @@ #include "util.h" #include "clinic/cursor.c.h" +static inline int +check_cursor_locked(pysqlite_Cursor *cur) +{ + if (cur->locked) { + PyErr_SetString(pysqlite_ProgrammingError, + "Recursive use of cursors not allowed."); + return 0; + } + return 1; +} + /*[clinic input] module _sqlite3 class _sqlite3.Cursor "pysqlite_Cursor *" "pysqlite_CursorType" @@ -47,6 +58,10 @@ pysqlite_cursor_init_impl(pysqlite_Cursor *self, pysqlite_Connection *connection) /*[clinic end generated code: output=ac59dce49a809ca8 input=a8a4f75ac90999b2]*/ { + if (!check_cursor_locked(self)) { + return -1; + } + Py_INCREF(connection); Py_XSETREF(self->connection, connection); Py_CLEAR(self->statement); @@ -407,12 +422,9 @@ static int check_cursor(pysqlite_Cursor* cur) return 0; } - if (cur->locked) { - PyErr_SetString(pysqlite_ProgrammingError, "Recursive use of cursors not allowed."); - return 0; - } - - return pysqlite_check_thread(cur->connection) && pysqlite_check_connection(cur->connection); + return (pysqlite_check_thread(cur->connection) + && pysqlite_check_connection(cur->connection) + && check_cursor_locked(cur)); } static PyObject * @@ -810,27 +822,29 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self) if (self->statement) { rc = pysqlite_step(self->statement->st, self->connection); if (PyErr_Occurred()) { - (void)pysqlite_statement_reset(self->statement); - Py_DECREF(next_row); - return NULL; + goto error; } if (rc != SQLITE_DONE && rc != SQLITE_ROW) { - (void)pysqlite_statement_reset(self->statement); - Py_DECREF(next_row); _pysqlite_seterror(self->connection->db, NULL); - return NULL; + goto error; } if (rc == SQLITE_ROW) { + self->locked = 1; // GH-80254: Prevent recursive use of cursors. self->next_row = _pysqlite_fetch_one_row(self); + self->locked = 0; if (self->next_row == NULL) { - (void)pysqlite_statement_reset(self->statement); - return NULL; + goto error; } } } return next_row; + +error: + (void)pysqlite_statement_reset(self->statement); + Py_DECREF(next_row); + return NULL; } /*[clinic input] @@ -973,6 +987,10 @@ static PyObject * pysqlite_cursor_close_impl(pysqlite_Cursor *self) /*[clinic end generated code: output=b6055e4ec6fe63b6 input=08b36552dbb9a986]*/ { + if (!check_cursor_locked(self)) { + return NULL; + } + if (!self->connection) { PyErr_SetString(pysqlite_ProgrammingError, "Base Cursor.__init__ not called."); From 0eef443f0142b8cee705a22d0d1c9df17be94f69 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 5 May 2022 21:38:14 -0700 Subject: [PATCH 145/237] Issues/88027: A potential double free in list_sort_impl (GH-92367) merge_freemem(): set keys to NULL do it's harmless to call this again. (cherry picked from commit 9652900969df77b1ac245595419431df19296af9) Co-authored-by: Tim Peters --- Objects/listobject.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Objects/listobject.c b/Objects/listobject.c index 533ee7436d3113..d3bc5766df7a0b 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -1548,8 +1548,10 @@ static void merge_freemem(MergeState *ms) { assert(ms != NULL); - if (ms->a.keys != ms->temparray) + if (ms->a.keys != ms->temparray) { PyMem_Free(ms->a.keys); + ms->a.keys = NULL; + } } /* Ensure enough temp memory for 'need' array slots is available. From 3db0e0b9f7a32246a0311ed4603b338a2ecf43a4 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 5 May 2022 22:15:53 -0700 Subject: [PATCH 146/237] NEWS: Reorder items by section (GH-92373) They caused duplicated sections. (cherry picked from commit 9b491ae04c900579ec82776aacdf71b2fd1e9d6a) Co-authored-by: Inada Naoki --- Misc/NEWS.d/3.5.2rc1.rst | 154 +++++++++++++++++++-------------------- Misc/NEWS.d/3.5.3rc1.rst | 46 ++++++------ Misc/NEWS.d/3.6.0a1.rst | 68 ++++++++--------- Misc/NEWS.d/3.6.0a2.rst | 88 +++++++++++----------- Misc/NEWS.d/3.6.0a3.rst | 46 ++++++------ Misc/NEWS.d/3.6.2rc1.rst | 26 +++---- 6 files changed, 214 insertions(+), 214 deletions(-) diff --git a/Misc/NEWS.d/3.5.2rc1.rst b/Misc/NEWS.d/3.5.2rc1.rst index d891fa0880dad1..01fcd866a896ae 100644 --- a/Misc/NEWS.d/3.5.2rc1.rst +++ b/Misc/NEWS.d/3.5.2rc1.rst @@ -1,7 +1,73 @@ +.. bpo: 26556 +.. date: 9636 +.. nonce: v5j2uL +.. release date: 2016-06-12 +.. original section: Library +.. section: Security + +Update expat to 2.1.1, fixes CVE-2015-1283. + +.. + +.. bpo: 0 +.. date: 9635 +.. nonce: E4ochz +.. original section: Library +.. section: Security + +Fix TLS stripping vulnerability in smtplib, CVE-2016-0772. Reported by Team +Oststrom + +.. + +.. bpo: 26839 +.. date: 9629 +.. nonce: yVvy7R +.. original section: Library +.. section: Security + +On Linux, :func:`os.urandom` now calls ``getrandom()`` with +``GRND_NONBLOCK`` to fall back on reading ``/dev/urandom`` if the urandom +entropy pool is not initialized yet. Patch written by Colm Buckley. + +.. + +.. bpo: 26657 +.. date: 9597 +.. nonce: C_-XFg +.. original section: Library +.. section: Security + +Fix directory traversal vulnerability with http.server on Windows. This +fixes a regression that was introduced in 3.3.4rc1 and 3.4.0rc1. Based on +patch by Philipp Hagemeister. + +.. + +.. bpo: 26313 +.. date: 9581 +.. nonce: LjZAjy +.. original section: Library +.. section: Security + +ssl.py _load_windows_store_certs fails if windows cert store is empty. Patch +by Baji. + +.. + +.. bpo: 25939 +.. date: 9561 +.. nonce: X49Fqd +.. original section: Library +.. section: Security + +On Windows open the cert store readonly in ssl.enum_certificates. + +.. + .. bpo: 27066 .. date: 9673 .. nonce: SNExZi -.. release date: 2016-06-12 .. section: Core and Builtins Fixed SystemError if a custom opener (for open()) returns a negative number @@ -373,27 +439,6 @@ PendingDeprecationWarning. .. -.. bpo: 26556 -.. date: 9636 -.. nonce: v5j2uL -.. original section: Library -.. section: Security - -Update expat to 2.1.1, fixes CVE-2015-1283. - -.. - -.. bpo: 0 -.. date: 9635 -.. nonce: E4ochz -.. original section: Library -.. section: Security - -Fix TLS stripping vulnerability in smtplib, CVE-2016-0772. Reported by Team -Oststrom - -.. - .. bpo: 21386 .. date: 9634 .. nonce: DjV72U @@ -449,18 +494,6 @@ build information. .. -.. bpo: 26839 -.. date: 9629 -.. nonce: yVvy7R -.. original section: Library -.. section: Security - -On Linux, :func:`os.urandom` now calls ``getrandom()`` with -``GRND_NONBLOCK`` to fall back on reading ``/dev/urandom`` if the urandom -entropy pool is not initialized yet. Patch written by Colm Buckley. - -.. - .. bpo: 27164 .. date: 9628 .. nonce: 6wmjx2 @@ -776,18 +809,6 @@ limits for multibyte character encodings like utf-8. .. -.. bpo: 26657 -.. date: 9597 -.. nonce: C_-XFg -.. original section: Library -.. section: Security - -Fix directory traversal vulnerability with http.server on Windows. This -fixes a regression that was introduced in 3.3.4rc1 and 3.4.0rc1. Based on -patch by Philipp Hagemeister. - -.. - .. bpo: 26717 .. date: 9596 .. nonce: jngTdu @@ -937,17 +958,6 @@ Peter Inglesby. .. -.. bpo: 26313 -.. date: 9581 -.. nonce: LjZAjy -.. original section: Library -.. section: Security - -ssl.py _load_windows_store_certs fails if windows cert store is empty. Patch -by Baji. - -.. - .. bpo: 26569 .. date: 9580 .. nonce: EX8vF1 @@ -1136,16 +1146,6 @@ socket) when verify_request() returns false. Patch by Aviv Palivoda. .. -.. bpo: 25939 -.. date: 9561 -.. nonce: X49Fqd -.. original section: Library -.. section: Security - -On Windows open the cert store readonly in ssl.enum_certificates. - -.. - .. bpo: 25995 .. date: 9560 .. nonce: NfcimP @@ -2154,6 +2154,16 @@ Excludes venv from library when generating embeddable distro. .. +.. bpo: 17500 +.. date: 9453 +.. nonce: QTZbRV +.. section: Windows + +Remove unused and outdated icons. (See also: +https://github.com/python/pythondotorg/issues/945) + +.. + .. bpo: 26799 .. date: 9457 .. nonce: gK2VXX @@ -2191,13 +2201,3 @@ Teo. .. section: Tools/Demos Fix variable name typo in Argument Clinic. - -.. - -.. bpo: 17500 -.. date: 9453 -.. nonce: QTZbRV -.. section: Windows - -Remove unused and outdated icons. (See also: -https://github.com/python/pythondotorg/issues/945) diff --git a/Misc/NEWS.d/3.5.3rc1.rst b/Misc/NEWS.d/3.5.3rc1.rst index 037cfe416510b9..2307fccbf6f92d 100644 --- a/Misc/NEWS.d/3.5.3rc1.rst +++ b/Misc/NEWS.d/3.5.3rc1.rst @@ -1,7 +1,29 @@ +.. release date: 2017-01-02 +.. bpo: 27278 +.. date: 9755 +.. nonce: y_HkGw +.. original section: Library +.. section: Security + +Fix os.urandom() implementation using getrandom() on Linux. Truncate size +to INT_MAX and loop until we collected enough random bytes, instead of +casting a directly Py_ssize_t to int. + +.. + +.. bpo: 22636 +.. date: 9753 +.. nonce: 3fQW_g +.. original section: Library +.. section: Security + +Avoid shell injection problems with ctypes.util.find_library(). + +.. + .. bpo: 29073 .. date: 9898 .. nonce: EFpHQ7 -.. release date: 2017-01-02 .. section: Core and Builtins bytearray formatting no longer truncates on first null byte. @@ -1406,18 +1428,6 @@ issue25782. .. -.. bpo: 27278 -.. date: 9755 -.. nonce: y_HkGw -.. original section: Library -.. section: Security - -Fix os.urandom() implementation using getrandom() on Linux. Truncate size -to INT_MAX and loop until we collected enough random bytes, instead of -casting a directly Py_ssize_t to int. - -.. - .. bpo: 26386 .. date: 9754 .. nonce: 9L3Ut4 @@ -1427,16 +1437,6 @@ Fixed ttk.TreeView selection operations with item id's containing spaces. .. -.. bpo: 22636 -.. date: 9753 -.. nonce: 3fQW_g -.. original section: Library -.. section: Security - -Avoid shell injection problems with ctypes.util.find_library(). - -.. - .. bpo: 16182 .. date: 9752 .. nonce: RgFXyr diff --git a/Misc/NEWS.d/3.6.0a1.rst b/Misc/NEWS.d/3.6.0a1.rst index 3fa356c56d94a0..53f09b3dfe3363 100644 --- a/Misc/NEWS.d/3.6.0a1.rst +++ b/Misc/NEWS.d/3.6.0a1.rst @@ -1,7 +1,40 @@ +.. release date: 2016-05-16 +.. bpo: 26657 +.. date: 9135 +.. nonce: C_-XFg +.. original section: Library +.. section: Security + +Fix directory traversal vulnerability with http.server on Windows. This +fixes a regression that was introduced in 3.3.4rc1 and 3.4.0rc1. Based on +patch by Philipp Hagemeister. + +.. + +.. bpo: 26313 +.. date: 9102 +.. nonce: LjZAjy +.. original section: Library +.. section: Security + +ssl.py _load_windows_store_certs fails if windows cert store is empty. Patch +by Baji. + +.. + +.. bpo: 25939 +.. date: 9076 +.. nonce: X49Fqd +.. original section: Library +.. section: Security + +On Windows open the cert store readonly in ssl.enum_certificates. + +.. + .. bpo: 20041 .. date: 9253 .. nonce: TypyGp -.. release date: 2016-05-16 .. section: Core and Builtins Fixed TypeError when frame.f_trace is set to None. Patch by Xavier de Gaye. @@ -1198,18 +1231,6 @@ limits for multibyte character encodings like utf-8. .. -.. bpo: 26657 -.. date: 9135 -.. nonce: C_-XFg -.. original section: Library -.. section: Security - -Fix directory traversal vulnerability with http.server on Windows. This -fixes a regression that was introduced in 3.3.4rc1 and 3.4.0rc1. Based on -patch by Philipp Hagemeister. - -.. - .. bpo: 26717 .. date: 9134 .. nonce: jngTdu @@ -1532,17 +1553,6 @@ tracemalloc to get the traceback where source object was allocated. .. -.. bpo: 26313 -.. date: 9102 -.. nonce: LjZAjy -.. original section: Library -.. section: Security - -ssl.py _load_windows_store_certs fails if windows cert store is empty. Patch -by Baji. - -.. - .. bpo: 26569 .. date: 9101 .. nonce: EX8vF1 @@ -1793,16 +1803,6 @@ handle_error() method, and will now to stop a single-threaded server. .. -.. bpo: 25939 -.. date: 9076 -.. nonce: X49Fqd -.. original section: Library -.. section: Security - -On Windows open the cert store readonly in ssl.enum_certificates. - -.. - .. bpo: 25995 .. date: 9075 .. nonce: NfcimP diff --git a/Misc/NEWS.d/3.6.0a2.rst b/Misc/NEWS.d/3.6.0a2.rst index fa050dec27ff03..1b336d7bc5137a 100644 --- a/Misc/NEWS.d/3.6.0a2.rst +++ b/Misc/NEWS.d/3.6.0a2.rst @@ -1,7 +1,40 @@ +.. release date: 2016-06-13 +.. bpo: 26556 +.. date: 9316 +.. nonce: v5j2uL +.. original section: Library +.. section: Security + +Update expat to 2.1.1, fixes CVE-2015-1283. + +.. + +.. bpo: 0 +.. date: 9315 +.. nonce: PHOAdg +.. original section: Library +.. section: Security + +Fix TLS stripping vulnerability in smtplib, CVE-2016-0772. Reported by Team +Oststrom. + +.. + +.. bpo: 26839 +.. date: 9303 +.. nonce: yVvy7R +.. original section: Library +.. section: Security + +On Linux, :func:`os.urandom` now calls ``getrandom()`` with +``GRND_NONBLOCK`` to fall back on reading ``/dev/urandom`` if the urandom +entropy pool is not initialized yet. Patch written by Colm Buckley. + +.. + .. bpo: 27095 .. date: 9332 .. nonce: 92UoyH -.. release date: 2016-06-13 .. section: Core and Builtins Simplified MAKE_FUNCTION and removed MAKE_CLOSURE opcodes. Patch by Demur @@ -159,27 +192,6 @@ Rees. .. -.. bpo: 26556 -.. date: 9316 -.. nonce: v5j2uL -.. original section: Library -.. section: Security - -Update expat to 2.1.1, fixes CVE-2015-1283. - -.. - -.. bpo: 0 -.. date: 9315 -.. nonce: PHOAdg -.. original section: Library -.. section: Security - -Fix TLS stripping vulnerability in smtplib, CVE-2016-0772. Reported by Team -Oststrom. - -.. - .. bpo: 21386 .. date: 9314 .. nonce: DjV72U @@ -294,18 +306,6 @@ build information. .. -.. bpo: 26839 -.. date: 9303 -.. nonce: yVvy7R -.. original section: Library -.. section: Security - -On Linux, :func:`os.urandom` now calls ``getrandom()`` with -``GRND_NONBLOCK`` to fall back on reading ``/dev/urandom`` if the urandom -entropy pool is not initialized yet. Patch written by Colm Buckley. - -.. - .. bpo: 23883 .. date: 9302 .. nonce: tsZUiM @@ -735,6 +735,16 @@ default when used interactively. .. +.. bpo: 17500 +.. date: 9257 +.. nonce: QTZbRV +.. section: Windows + +Remove unused and outdated icons. (See also: +https://github.com/python/pythondotorg/issues/945) + +.. + .. bpo: 27229 .. date: 9259 .. nonce: C2NDch @@ -755,16 +765,6 @@ Update OS X 10.5+ 32-bit-only installer to build and link with OpenSSL .. -.. bpo: 17500 -.. date: 9257 -.. nonce: QTZbRV -.. section: Windows - -Remove unused and outdated icons. (See also: -https://github.com/python/pythondotorg/issues/945) - -.. - .. bpo: 27186 .. date: 9256 .. nonce: Ll8R-t diff --git a/Misc/NEWS.d/3.6.0a3.rst b/Misc/NEWS.d/3.6.0a3.rst index 4b0000b0e7975a..62892b59ded6af 100644 --- a/Misc/NEWS.d/3.6.0a3.rst +++ b/Misc/NEWS.d/3.6.0a3.rst @@ -1,7 +1,29 @@ +.. release date: 2016-07-11 +.. bpo: 27278 +.. date: 9361 +.. nonce: y_HkGw +.. original section: Library +.. section: Security + +Fix os.urandom() implementation using getrandom() on Linux. Truncate size +to INT_MAX and loop until we collected enough random bytes, instead of +casting a directly Py_ssize_t to int. + +.. + +.. bpo: 22636 +.. date: 9357 +.. nonce: 3fQW_g +.. original section: Library +.. section: Security + +Avoid shell injection problems with ctypes.util.find_library(). + +.. + .. bpo: 27473 .. date: 9385 .. nonce: _nOtTA -.. release date: 2016-07-11 .. section: Core and Builtins Fixed possible integer overflow in bytes and bytearray concatenations. @@ -248,18 +270,6 @@ issue25782. .. -.. bpo: 27278 -.. date: 9361 -.. nonce: y_HkGw -.. original section: Library -.. section: Security - -Fix os.urandom() implementation using getrandom() on Linux. Truncate size -to INT_MAX and loop until we collected enough random bytes, instead of -casting a directly Py_ssize_t to int. - -.. - .. bpo: 16864 .. date: 9360 .. nonce: W7tJDa @@ -289,16 +299,6 @@ env var PAGER). .. -.. bpo: 22636 -.. date: 9357 -.. nonce: 3fQW_g -.. original section: Library -.. section: Security - -Avoid shell injection problems with ctypes.util.find_library(). - -.. - .. bpo: 16182 .. date: 9356 .. nonce: RgFXyr diff --git a/Misc/NEWS.d/3.6.2rc1.rst b/Misc/NEWS.d/3.6.2rc1.rst index 20cabb05fa3b1c..cdf4c3d541c4ca 100644 --- a/Misc/NEWS.d/3.6.2rc1.rst +++ b/Misc/NEWS.d/3.6.2rc1.rst @@ -1,7 +1,19 @@ +.. release date: 2017-06-17 +.. bpo: 29591 +.. date: 9966 +.. nonce: ExKblw +.. original section: Library +.. section: Security + +Update expat copy from 2.1.1 to 2.2.0 to get fixes of CVE-2016-0718 and +CVE-2016-4472. See https://sourceforge.net/p/expat/bugs/537/ for more +information. + +.. + .. bpo: 30682 .. date: 9989 .. nonce: zZm88E -.. release date: 2017-06-17 .. section: Core and Builtins Removed a too-strict assertion that failed for certain f-strings, such as @@ -224,18 +236,6 @@ with misplaced inline modifier. Patch by Roy Williams. .. -.. bpo: 29591 -.. date: 9966 -.. nonce: ExKblw -.. original section: Library -.. section: Security - -Update expat copy from 2.1.1 to 2.2.0 to get fixes of CVE-2016-0718 and -CVE-2016-4472. See https://sourceforge.net/p/expat/bugs/537/ for more -information. - -.. - .. bpo: 24484 .. date: 9965 .. nonce: fNS32j From 367faf71eae963e613cb4404e24748c91baa4190 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 6 May 2022 02:55:01 -0700 Subject: [PATCH 147/237] Document the lifetime of `PyUnicode_AsUTF8String` (GH-92325) The current wording implied this, but didn't state it explicitly. (cherry picked from commit 740da8d37a84638f4a8893bee3648f36fc6beb0f) Co-authored-by: Matt Wozniski --- Doc/c-api/unicode.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index a08cebcc000d0d..cf7d2232125c89 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -1093,7 +1093,8 @@ These are the UTF-8 codec APIs: This caches the UTF-8 representation of the string in the Unicode object, and subsequent calls will return a pointer to the same buffer. The caller is not - responsible for deallocating the buffer. + responsible for deallocating the buffer. The buffer is deallocated and + pointers to it become invalid when the Unicode object is garbage collected. .. versionadded:: 3.3 From b5f5993dfe1c9e5dc48e3e514f282464da9fb4a3 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 6 May 2022 03:58:16 -0700 Subject: [PATCH 148/237] Add source for character mappings (GH-92014) (#92389) (cherry picked from commit d707d073be5ecacb7ad341a1c1716f4998907d6b) Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> --- Lib/html/entities.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/html/entities.py b/Lib/html/entities.py index 91ea5da2af49d3..dc508631ac4789 100644 --- a/Lib/html/entities.py +++ b/Lib/html/entities.py @@ -4,6 +4,7 @@ # maps the HTML entity name to the Unicode code point +# from https://html.spec.whatwg.org/multipage/named-characters.html name2codepoint = { 'AElig': 0x00c6, # latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1 'Aacute': 0x00c1, # latin capital letter A with acute, U+00C1 ISOlat1 From 229dc17f7a05c87e8b00c6882476fc4c076f9779 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 6 May 2022 05:47:09 -0700 Subject: [PATCH 149/237] gh-92047: Py_GetVersion multi-digit minor version (GH-92047) (GH-92048) (#92330) (cherry picked from commit 43b135f94ebf3e6e84ddb0f75ed8510b96a610e4) Co-authored-by: Robert Howlett Co-authored-by: Robert Howlett --- Doc/c-api/init.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index a5227904460017..a44442a5015550 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -529,7 +529,7 @@ Process-wide parameters .. index:: single: version (in module sys) The first word (up to the first space character) is the current Python version; - the first three characters are the major and minor version separated by a + the first characters are the major and minor version separated by a period. The returned string points into static storage; the caller should not modify its value. The value is available to Python code as :data:`sys.version`. From 17f3b5cbfaada66b45422e80c06b0c5f8157a736 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 6 May 2022 07:12:59 -0700 Subject: [PATCH 150/237] gh-92368: Fix missing possessive apostrophe (GH-92397) * Fix missing possessive apostrophe (cherry picked from commit a79001ee16b3ea8b5d0fad595c969d9e1b7627f3) Co-authored-by: gophra <105054704+gophra@users.noreply.github.com> --- Doc/tutorial/stdlib.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/tutorial/stdlib.rst b/Doc/tutorial/stdlib.rst index aac1ae3a8a6b42..6871ed1e8689bc 100644 --- a/Doc/tutorial/stdlib.rst +++ b/Doc/tutorial/stdlib.rst @@ -327,7 +327,7 @@ Python has a "batteries included" philosophy. This is best seen through the sophisticated and robust capabilities of its larger packages. For example: * The :mod:`xmlrpc.client` and :mod:`xmlrpc.server` modules make implementing - remote procedure calls into an almost trivial task. Despite the modules + remote procedure calls into an almost trivial task. Despite the modules' names, no direct knowledge or handling of XML is needed. * The :mod:`email` package is a library for managing email messages, including From 4674b315e555828e5cb15bedcf2c495669670cbb Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Fri, 6 May 2022 21:01:23 -0700 Subject: [PATCH 151/237] [3.10] gh-92112: Fix crash triggered by an evil custom `mro()` (GH-92113) (#92370) (cherry picked from commit 85354ed78c0edb6d81a2bd53cabc85e547b8b26e) Co-authored-by: Alexey Izbyshev --- Lib/test/test_descr.py | 17 ++++++++++++++++ ...2-05-01-10-58-38.gh-issue-92112.lLJemu.rst | 1 + Objects/typeobject.c | 20 ++++++++++--------- 3 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-05-01-10-58-38.gh-issue-92112.lLJemu.rst diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index f3dd1b32e2afa8..b174e7168f7db8 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -5737,6 +5737,23 @@ def mro(cls): class A(metaclass=M): pass + def test_disappearing_custom_mro(self): + """ + gh-92112: A custom mro() returning a result conflicting with + __bases__ and deleting itself caused a double free. + """ + class B: + pass + + class M(DebugHelperMeta): + def mro(cls): + del M.mro + return (B,) + + with self.assertRaises(TypeError): + class A(metaclass=M): + pass + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-05-01-10-58-38.gh-issue-92112.lLJemu.rst b/Misc/NEWS.d/next/Core and Builtins/2022-05-01-10-58-38.gh-issue-92112.lLJemu.rst new file mode 100644 index 00000000000000..00c938e89f4387 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-05-01-10-58-38.gh-issue-92112.lLJemu.rst @@ -0,0 +1 @@ +Fix crash triggered by an evil custom ``mro()`` on a metaclass. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index b3ba1208eb253b..50f2742f676f68 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -369,22 +369,26 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) { Py_ssize_t i, n; int custom = !Py_IS_TYPE(type, &PyType_Type); int unbound; - PyObject *mro_meth = NULL; - PyObject *type_mro_meth = NULL; if (custom) { + PyObject *mro_meth, *type_mro_meth; mro_meth = lookup_maybe_method( (PyObject *)type, &PyId_mro, &unbound); - if (mro_meth == NULL) + if (mro_meth == NULL) { goto clear; + } type_mro_meth = lookup_maybe_method( (PyObject *)&PyType_Type, &PyId_mro, &unbound); - if (type_mro_meth == NULL) + if (type_mro_meth == NULL) { + Py_DECREF(mro_meth); goto clear; - if (mro_meth != type_mro_meth) + } + int custom_mro = (mro_meth != type_mro_meth); + Py_DECREF(mro_meth); + Py_DECREF(type_mro_meth); + if (custom_mro) { goto clear; - Py_XDECREF(mro_meth); - Py_XDECREF(type_mro_meth); + } } n = PyTuple_GET_SIZE(bases); for (i = 0; i < n; i++) { @@ -400,8 +404,6 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) { } return; clear: - Py_XDECREF(mro_meth); - Py_XDECREF(type_mro_meth); type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG; type->tp_version_tag = 0; /* 0 is not a valid version tag */ } From 731d893bdf29c8048b392691f9dee74ed4c9c9b3 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sun, 8 May 2022 22:31:40 +0900 Subject: [PATCH 152/237] [3.10] gh-92448: Update the documentation builder to render the GitHub issue (GH-92449). (GH-92457) --- Doc/tools/extensions/pyspecific.py | 9 +++++---- Misc/NEWS.d/3.10.0a6.rst | 2 +- Misc/NEWS.d/3.10.0a7.rst | 2 +- Misc/NEWS.d/3.10.0b1.rst | 4 ++-- Misc/NEWS.d/3.10.1.rst | 2 +- Misc/NEWS.d/3.7.0a3.rst | 2 +- Misc/NEWS.d/3.8.0a1.rst | 2 +- Misc/NEWS.d/3.9.0a1.rst | 2 +- 8 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index cbb7638627ef14..27004afc0bab99 100644 --- a/Doc/tools/extensions/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -429,7 +429,8 @@ def run(self): # Support for including Misc/NEWS -issue_re = re.compile('(?:[Ii]ssue #|bpo-)([0-9]+)') +issue_re = re.compile('(?:[Ii]ssue #|bpo-)([0-9]+)', re.I) +gh_issue_re = re.compile('(?:gh-issue-|gh-)([0-9]+)', re.I) whatsnew_re = re.compile(r"(?im)^what's new in (.*?)\??$") @@ -456,9 +457,9 @@ def run(self): text = 'The NEWS file is not available.' node = nodes.strong(text, text) return [node] - content = issue_re.sub(r'`bpo-\1 `__', - content) + content = issue_re.sub(r':issue:`\1`', content) + # Fallback handling for the GitHub issue + content = gh_issue_re.sub(r':gh:`\1`', content) content = whatsnew_re.sub(r'\1', content) # remove first 3 lines as they are the main heading lines = ['.. default-role:: obj', ''] + content.splitlines()[3:] diff --git a/Misc/NEWS.d/3.10.0a6.rst b/Misc/NEWS.d/3.10.0a6.rst index a4ee9ae098bd93..803df6f51ce628 100644 --- a/Misc/NEWS.d/3.10.0a6.rst +++ b/Misc/NEWS.d/3.10.0a6.rst @@ -232,7 +232,7 @@ now result in :exc:`MemoryError`. Patch by Erlend E. Aasland. .. section: Library Fix segfault in :meth:`sqlite3.Connection.backup` if no argument was -provided. The regression was introduced by GH-23838. Patch by Erlend E. +provided. The regression was introduced by PR 23838. Patch by Erlend E. Aasland. .. diff --git a/Misc/NEWS.d/3.10.0a7.rst b/Misc/NEWS.d/3.10.0a7.rst index f62be491d56dd6..864dc2cb90a9f1 100644 --- a/Misc/NEWS.d/3.10.0a7.rst +++ b/Misc/NEWS.d/3.10.0a7.rst @@ -574,7 +574,7 @@ raised. Patch by Erlend E. Aasland. .. nonce: t9XEkQ .. section: Library -Fix a regression introduced in GH-24562, where an empty bytestring was +Fix a regression introduced in PR 24562, where an empty bytestring was fetched as ``None`` instead of ``b''`` in :mod:`sqlite3`. Patch by Mariusz Felisiak. diff --git a/Misc/NEWS.d/3.10.0b1.rst b/Misc/NEWS.d/3.10.0b1.rst index 4731dca2e74cf7..345a9173a0dd78 100644 --- a/Misc/NEWS.d/3.10.0b1.rst +++ b/Misc/NEWS.d/3.10.0b1.rst @@ -941,7 +941,7 @@ result from ``entry_points()`` as deprecated. .. -.. bpo: 47383 +.. gh: 47383 .. date: 2021-04-08-19-32-26 .. nonce: YI1hdL .. section: Library @@ -1001,7 +1001,7 @@ some :mod:`dataclasses`. Fix :mod:`sqlite3` regression for zero-sized blobs with converters, where ``b""`` was returned instead of ``None``. The regression was introduced by -GH-24723. Patch by Erlend E. Aasland. +PR 24723. Patch by Erlend E. Aasland. .. diff --git a/Misc/NEWS.d/3.10.1.rst b/Misc/NEWS.d/3.10.1.rst index 0f8938ab6154d8..8ef3cd124619eb 100644 --- a/Misc/NEWS.d/3.10.1.rst +++ b/Misc/NEWS.d/3.10.1.rst @@ -730,7 +730,7 @@ Patch by Kyungmin Lee. .. section: Library Fix typo: ``importlib.find_loader`` is really slated for removal in Python -3.12 not 3.10, like the others in GH-25169. +3.12 not 3.10, like the others in PR 25169. Patch by Hugo van Kemenade. diff --git a/Misc/NEWS.d/3.7.0a3.rst b/Misc/NEWS.d/3.7.0a3.rst index 067720efa516e0..6576c1fadbff6d 100644 --- a/Misc/NEWS.d/3.7.0a3.rst +++ b/Misc/NEWS.d/3.7.0a3.rst @@ -288,7 +288,7 @@ by Nir Soffer. .. -.. bpo: 321010 +.. bpo: 32101 .. date: 2017-11-29-00-42-47 .. nonce: -axD5l .. section: Library diff --git a/Misc/NEWS.d/3.8.0a1.rst b/Misc/NEWS.d/3.8.0a1.rst index 5cd3fa32105c27..09b858d250c337 100644 --- a/Misc/NEWS.d/3.8.0a1.rst +++ b/Misc/NEWS.d/3.8.0a1.rst @@ -4617,7 +4617,7 @@ Based on patch by c-fos. .. section: Library Remove HMAC default to md5 marked for removal in 3.8 (removal originally -planned in 3.6, bump to 3.8 in gh-7062). +planned in 3.6, bump to 3.8 in PR 7062). .. diff --git a/Misc/NEWS.d/3.9.0a1.rst b/Misc/NEWS.d/3.9.0a1.rst index a9b6694c133f19..45f232f1948d5d 100644 --- a/Misc/NEWS.d/3.9.0a1.rst +++ b/Misc/NEWS.d/3.9.0a1.rst @@ -1335,7 +1335,7 @@ module on POSIX systems. .. nonce: 9TWMlz .. section: Library -Revert GH-15522, which introduces a regression in +Revert PR 15522, which introduces a regression in :meth:`mimetypes.guess_type` due to improper handling of filenames as urls. .. From 80ce70110b61db63a7dec33df59369b0b1b09144 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 8 May 2022 08:04:18 -0700 Subject: [PATCH 153/237] gh-92417: `typing` docs: `from __future__ import annotations` can be used in all supported Python versions (GH-92418) (cherry picked from commit e5b4bd4d60aaf0292c5b9d628512145b8987b3c6) Co-authored-by: Alex Waygood --- Doc/library/typing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index bcf2b22b1a3c2a..9936f1a3e57c37 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -2290,7 +2290,7 @@ Constant .. note:: - If ``from __future__ import annotations`` is used in Python 3.7 or later, + If ``from __future__ import annotations`` is used, annotations are not evaluated at function definition time. Instead, they are stored as strings in ``__annotations__``. This makes it unnecessary to use quotes around the annotation From 8c42fefa392e768efc4ce15099800dbe212752dc Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 8 May 2022 08:26:06 -0700 Subject: [PATCH 154/237] [3.10] gh-92417: `stdtypes` docs: delete discussion of Python 2 differences (GH-92423) (GH-92473) Given that 2.7 has now been end-of-life for two and a half years, I don't think we need such a detailed explanation here anymore of the differences between Python 2 and Python 3. (cherry picked from commit 8efda1e7c6343b1671d93837bf2c146e4cf77bbf) Co-authored-by: Alex Waygood Automerge-Triggered-By: GH:serhiy-storchaka --- Doc/library/stdtypes.rst | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 365680d4503bad..dd7c1ab5c9d1ef 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2535,16 +2535,6 @@ The representation of bytes objects uses the literal format (``b'...'``) since it is often more useful than e.g. ``bytes([46, 46, 46])``. You can always convert a bytes object into a list of integers using ``list(b)``. -.. note:: - For Python 2.x users: In the Python 2.x series, a variety of implicit - conversions between 8-bit strings (the closest thing 2.x offers to a - built-in binary data type) and Unicode strings were permitted. This was a - backwards compatibility workaround to account for the fact that Python - originally only supported 8-bit text, and Unicode text was a later - addition. In Python 3.x, those implicit conversions are gone - conversions - between 8-bit binary data and Unicode text must be explicit, and bytes and - string objects will always compare unequal. - .. _typebytearray: From a7d869a2ea9759b7c28837b11992e7cee19e3622 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 8 May 2022 08:28:06 -0700 Subject: [PATCH 155/237] [3.10] gh-77630: Change Charset to charset (GH-92439) (GH-92476) (cherry picked from commit 8f293180791f2836570bdfc29aadba04a538d435) Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> Automerge-Triggered-By: GH:serhiy-storchaka --- Doc/library/email.charset.rst | 14 +++++++------- Lib/email/charset.py | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Doc/library/email.charset.rst b/Doc/library/email.charset.rst index 38fda23bd8237f..adbe6c1c7d29b8 100644 --- a/Doc/library/email.charset.rst +++ b/Doc/library/email.charset.rst @@ -58,9 +58,9 @@ Import this class from the :mod:`email.charset` module. .. attribute:: header_encoding If the character set must be encoded before it can be used in an email - header, this attribute will be set to ``Charset.QP`` (for - quoted-printable), ``Charset.BASE64`` (for base64 encoding), or - ``Charset.SHORTEST`` for the shortest of QP or BASE64 encoding. Otherwise, + header, this attribute will be set to ``charset.QP`` (for + quoted-printable), ``charset.BASE64`` (for base64 encoding), or + ``charset.SHORTEST`` for the shortest of QP or BASE64 encoding. Otherwise, it will be ``None``. @@ -68,7 +68,7 @@ Import this class from the :mod:`email.charset` module. Same as *header_encoding*, but describes the encoding for the mail message's body, which indeed may be different than the header encoding. - ``Charset.SHORTEST`` is not allowed for *body_encoding*. + ``charset.SHORTEST`` is not allowed for *body_encoding*. .. attribute:: output_charset @@ -175,9 +175,9 @@ new entries to the global character set, alias, and codec registries: *charset* is the input character set, and must be the canonical name of a character set. - Optional *header_enc* and *body_enc* is either ``Charset.QP`` for - quoted-printable, ``Charset.BASE64`` for base64 encoding, - ``Charset.SHORTEST`` for the shortest of quoted-printable or base64 encoding, + Optional *header_enc* and *body_enc* is either ``charset.QP`` for + quoted-printable, ``charset.BASE64`` for base64 encoding, + ``charset.SHORTEST`` for the shortest of quoted-printable or base64 encoding, or ``None`` for no encoding. ``SHORTEST`` is only valid for *header_enc*. The default is ``None`` for no encoding. diff --git a/Lib/email/charset.py b/Lib/email/charset.py index d3d759ad9115f0..791b6584b24757 100644 --- a/Lib/email/charset.py +++ b/Lib/email/charset.py @@ -112,8 +112,8 @@ def add_charset(charset, header_enc=None, body_enc=None, output_charset=None): charset is the input character set, and must be the canonical name of a character set. - Optional header_enc and body_enc is either Charset.QP for - quoted-printable, Charset.BASE64 for base64 encoding, Charset.SHORTEST for + Optional header_enc and body_enc is either charset.QP for + quoted-printable, charset.BASE64 for base64 encoding, charset.SHORTEST for the shortest of qp or base64 encoding, or None for no encoding. SHORTEST is only valid for header_enc. It describes how message headers and message bodies in the input charset are to be encoded. Default is no @@ -185,13 +185,13 @@ class Charset: header_encoding: If the character set must be encoded before it can be used in an email header, this attribute will be set to - Charset.QP (for quoted-printable), Charset.BASE64 (for - base64 encoding), or Charset.SHORTEST for the shortest of + charset.QP (for quoted-printable), charset.BASE64 (for + base64 encoding), or charset.SHORTEST for the shortest of QP or BASE64 encoding. Otherwise, it will be None. body_encoding: Same as header_encoding, but describes the encoding for the mail message's body, which indeed may be different than the - header encoding. Charset.SHORTEST is not allowed for + header encoding. charset.SHORTEST is not allowed for body_encoding. output_charset: Some character sets must be converted before they can be From f40731fb518c10f70239e04ac86593d4bc84b506 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 8 May 2022 08:28:47 -0700 Subject: [PATCH 156/237] [3.10] GH-92431: Fix footnotes in Doc/c-api/exceptions.rst (GH-92432) (GH-92470) * Remove redundant footnote ref: the footnote has been removed * Fix footnote ref to match footnote * Convert footnotes into reST footnotes: will error if missing (cherry picked from commit 788ef54bc94b0a7aa2a93f626e4067ab8561424c) Co-authored-by: Hugo van Kemenade Automerge-Triggered-By: GH:serhiy-storchaka --- Doc/c-api/exceptions.rst | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index 7deef83b2789a9..fc90fa2b746e36 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -889,11 +889,11 @@ the variables: +-----------------------------------------+---------------------------------+----------+ | C Name | Python Name | Notes | +=========================================+=================================+==========+ -| :c:data:`PyExc_BaseException` | :exc:`BaseException` | \(1) | +| :c:data:`PyExc_BaseException` | :exc:`BaseException` | [1]_ | +-----------------------------------------+---------------------------------+----------+ -| :c:data:`PyExc_Exception` | :exc:`Exception` | \(1) | +| :c:data:`PyExc_Exception` | :exc:`Exception` | [1]_ | +-----------------------------------------+---------------------------------+----------+ -| :c:data:`PyExc_ArithmeticError` | :exc:`ArithmeticError` | \(1) | +| :c:data:`PyExc_ArithmeticError` | :exc:`ArithmeticError` | [1]_ | +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_AssertionError` | :exc:`AssertionError` | | +-----------------------------------------+---------------------------------+----------+ @@ -939,7 +939,7 @@ the variables: +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_KeyboardInterrupt` | :exc:`KeyboardInterrupt` | | +-----------------------------------------+---------------------------------+----------+ -| :c:data:`PyExc_LookupError` | :exc:`LookupError` | \(1) | +| :c:data:`PyExc_LookupError` | :exc:`LookupError` | [1]_ | +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_MemoryError` | :exc:`MemoryError` | | +-----------------------------------------+---------------------------------+----------+ @@ -951,7 +951,7 @@ the variables: +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_NotImplementedError` | :exc:`NotImplementedError` | | +-----------------------------------------+---------------------------------+----------+ -| :c:data:`PyExc_OSError` | :exc:`OSError` | \(1) | +| :c:data:`PyExc_OSError` | :exc:`OSError` | [1]_ | +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_OverflowError` | :exc:`OverflowError` | | +-----------------------------------------+---------------------------------+----------+ @@ -961,7 +961,7 @@ the variables: +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_RecursionError` | :exc:`RecursionError` | | +-----------------------------------------+---------------------------------+----------+ -| :c:data:`PyExc_ReferenceError` | :exc:`ReferenceError` | \(2) | +| :c:data:`PyExc_ReferenceError` | :exc:`ReferenceError` | | +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_RuntimeError` | :exc:`RuntimeError` | | +-----------------------------------------+---------------------------------+----------+ @@ -1026,7 +1026,7 @@ These are compatibility aliases to :c:data:`PyExc_OSError`: +-------------------------------------+----------+ | :c:data:`PyExc_IOError` | | +-------------------------------------+----------+ -| :c:data:`PyExc_WindowsError` | \(3) | +| :c:data:`PyExc_WindowsError` | [2]_ | +-------------------------------------+----------+ .. versionchanged:: 3.3 @@ -1034,10 +1034,10 @@ These are compatibility aliases to :c:data:`PyExc_OSError`: Notes: -(1) +.. [1] This is a base class for other standard exceptions. -(2) +.. [2] Only defined on Windows; protect code that uses this by testing that the preprocessor macro ``MS_WINDOWS`` is defined. @@ -1067,7 +1067,7 @@ the variables: +------------------------------------------+---------------------------------+----------+ | C Name | Python Name | Notes | +==========================================+=================================+==========+ -| :c:data:`PyExc_Warning` | :exc:`Warning` | \(1) | +| :c:data:`PyExc_Warning` | :exc:`Warning` | [3]_ | +------------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_BytesWarning` | :exc:`BytesWarning` | | +------------------------------------------+---------------------------------+----------+ @@ -1095,5 +1095,5 @@ the variables: Notes: -(1) +.. [3] This is a base class for other standard warning categories. From 45ed69b200e4de61fc469da3091da7c1fe0b0f39 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 8 May 2022 08:29:50 -0700 Subject: [PATCH 157/237] [3.10] gh-92417: `doctest` docs: remove references to Python <3.6 (GH-92420) (GH-92468) (cherry picked from commit 5639ea1ef9ba8452f81b61ad73152bd1bf1fd3a6) Co-authored-by: Alex Waygood Automerge-Triggered-By: GH:serhiy-storchaka --- Doc/library/doctest.rst | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst index a77322f83acbde..146fa5e775be46 100644 --- a/Doc/library/doctest.rst +++ b/Doc/library/doctest.rst @@ -288,10 +288,6 @@ strings are treated as if they were docstrings. In output, a key ``K`` in Any classes found are recursively searched similarly, to test docstrings in their contained methods and nested classes. -.. impl-detail:: - Prior to version 3.4, extension modules written in C were not fully - searched by doctest. - .. _doctest-finding-examples: @@ -786,11 +782,6 @@ instead. Another is to do :: >>> d ['Harry', 'Hermione'] -.. note:: - - Before Python 3.6, when printing a dict, Python did not guarantee that - the key-value pairs was printed in any particular order. - There are others, but you get the idea. Another bad idea is to print things that embed an object address, like :: From 2164b5bad76663dcd1639a4ab5be5a7220ea9b6e Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 8 May 2022 08:30:18 -0700 Subject: [PATCH 158/237] [3.10] gh-92417: `json` docs: `dict` is ordered on all supported Python versions (GH-92422) (GH-92465) (cherry picked from commit bc098cfdb756f207d8fa84793e8ad91a2f263efb) Co-authored-by: Alex Waygood Automerge-Triggered-By: GH:serhiy-storchaka --- Doc/library/json.rst | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Doc/library/json.rst b/Doc/library/json.rst index 1810e04cc83495..608e70df5b14c9 100644 --- a/Doc/library/json.rst +++ b/Doc/library/json.rst @@ -125,13 +125,6 @@ See :ref:`json-commandline` for detailed documentation. This module's encoders and decoders preserve input and output order by default. Order is only lost if the underlying containers are unordered. - Prior to Python 3.7, :class:`dict` was not guaranteed to be ordered, so - inputs and outputs were typically scrambled unless - :class:`collections.OrderedDict` was specifically requested. Starting - with Python 3.7, the regular :class:`dict` became order preserving, so - it is no longer necessary to specify :class:`collections.OrderedDict` for - JSON generation and parsing. - Basic Usage ----------- From e363034752dbc02cb8b21762ed70cc1c1e3e7066 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 8 May 2022 08:30:43 -0700 Subject: [PATCH 159/237] [3.10] gh-92417: `asyncio` docs: `asyncio.run()` is available on all supported Python versions (GH-92419) (GH-92463) (cherry picked from commit f4e317b304c7f86e48885b4b74c7a8826648922c) Co-authored-by: Alex Waygood Automerge-Triggered-By: GH:serhiy-storchaka --- Doc/library/asyncio.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/Doc/library/asyncio.rst b/Doc/library/asyncio.rst index 94a853259d3483..a6429394389b10 100644 --- a/Doc/library/asyncio.rst +++ b/Doc/library/asyncio.rst @@ -17,7 +17,6 @@ await asyncio.sleep(1) print('... World!') - # Python 3.7+ asyncio.run(main()) asyncio is a library to write **concurrent** code using From 15cb6e8b8b84f4ccc4a9215fd0c0477abfe4015e Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 8 May 2022 09:03:09 -0700 Subject: [PATCH 160/237] gh-92417: `logging` docs: Remove warning that only applies to Python <3.2 (GH-92425) (cherry picked from commit 318c4e91ef166bcd5d513bb42b9156d54d423d4a) Co-authored-by: Alex Waygood --- Doc/library/logging.rst | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 74b1f69caec5c2..b32af94e85d012 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -1080,16 +1080,6 @@ functions. Logs a message with level *level* on the root logger. The other arguments are interpreted as for :func:`debug`. - .. note:: The above module-level convenience functions, which delegate to the - root logger, call :func:`basicConfig` to ensure that at least one handler - is available. Because of this, they should *not* be used in threads, - in versions of Python earlier than 2.7.1 and 3.2, unless at least one - handler has been added to the root logger *before* the threads are - started. In earlier versions of Python, due to a thread safety shortcoming - in :func:`basicConfig`, this can (under rare circumstances) lead to - handlers being added multiple times to the root logger, which can in turn - lead to multiple messages for the same event. - .. function:: disable(level=CRITICAL) Provides an overriding level *level* for all loggers which takes precedence over From 1dbf69979fb1f104c7607a412b46d0d24d480b5a Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 8 May 2022 09:32:20 -0700 Subject: [PATCH 161/237] gh-80856: doc: reveal doctest directives (GH-92318) * Doc: Reveal doctest directives. * Fix whitespace. Co-authored-by: Julien Palard Co-authored-by: Ezio Melotti (cherry picked from commit 7b024e3a3f77027f747da7580ed0a3ed2dec276a) Co-authored-by: Davide Rizzo --- Doc/library/doctest.rst | 54 ++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst index 146fa5e775be46..59091e48d309f1 100644 --- a/Doc/library/doctest.rst +++ b/Doc/library/doctest.rst @@ -715,36 +715,51 @@ above. An example's doctest directives modify doctest's behavior for that single example. Use ``+`` to enable the named behavior, or ``-`` to disable it. -For example, this test passes:: +For example, this test passes: - >>> print(list(range(20))) # doctest: +NORMALIZE_WHITESPACE +.. doctest:: + :no-trim-doctest-flags: + + >>> print(list(range(20))) # doctest: +NORMALIZE_WHITESPACE [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] Without the directive it would fail, both because the actual output doesn't have two blanks before the single-digit list elements, and because the actual output is on a single line. This test also passes, and also requires a directive to do -so:: +so: + +.. doctest:: + :no-trim-doctest-flags: - >>> print(list(range(20))) # doctest: +ELLIPSIS + >>> print(list(range(20))) # doctest: +ELLIPSIS [0, 1, ..., 18, 19] Multiple directives can be used on a single physical line, separated by -commas:: +commas: - >>> print(list(range(20))) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE +.. doctest:: + :no-trim-doctest-flags: + + >>> print(list(range(20))) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE [0, 1, ..., 18, 19] If multiple directive comments are used for a single example, then they are -combined:: +combined: + +.. doctest:: + :no-trim-doctest-flags: - >>> print(list(range(20))) # doctest: +ELLIPSIS - ... # doctest: +NORMALIZE_WHITESPACE + >>> print(list(range(20))) # doctest: +ELLIPSIS + ... # doctest: +NORMALIZE_WHITESPACE [0, 1, ..., 18, 19] As the previous example shows, you can add ``...`` lines to your example containing only directives. This can be useful when an example is too long for -a directive to comfortably fit on the same line:: +a directive to comfortably fit on the same line: + +.. doctest:: + :no-trim-doctest-flags: >>> print(list(range(5)) + list(range(10, 20)) + list(range(30, 40))) ... # doctest: +ELLIPSIS @@ -784,18 +799,23 @@ instead. Another is to do :: There are others, but you get the idea. -Another bad idea is to print things that embed an object address, like :: +Another bad idea is to print things that embed an object address, like + +.. doctest:: - >>> id(1.0) # certain to fail some of the time + >>> id(1.0) # certain to fail some of the time # doctest: +SKIP 7948648 >>> class C: pass - >>> C() # the default repr() for instances embeds an address - <__main__.C instance at 0x00AC18F0> + >>> C() # the default repr() for instances embeds an address # doctest: +SKIP + + +The :const:`ELLIPSIS` directive gives a nice approach for the last example: -The :const:`ELLIPSIS` directive gives a nice approach for the last example:: +.. doctest:: + :no-trim-doctest-flags: - >>> C() #doctest: +ELLIPSIS - <__main__.C instance at 0x...> + >>> C() # doctest: +ELLIPSIS + Floating-point numbers are also subject to small output variations across platforms, because Python defers to the platform C library for float formatting, From b795376a628ae7cc354addbb926d724ebe364fec Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Sun, 8 May 2022 10:12:46 -0700 Subject: [PATCH 162/237] [3.10] gh-90622: Do not spawn ProcessPool workers on demand via fork method. (GH-91598) (#92497) Do not spawn ProcessPool workers on demand when they spawn via fork. This avoids potential deadlocks in the child processes due to forking from a multithreaded process.. (cherry picked from commit ebb37fc3fdcb03db4e206db017eeef7aaffbae84) Co-authored-by: Gregory P. Smith --- Lib/concurrent/futures/process.py | 42 +++++++++++++++---- Lib/test/test_concurrent_futures.py | 12 +++++- ...2-04-15-22-07-36.gh-issue-90622.0C6l8h.rst | 4 ++ 3 files changed, 48 insertions(+), 10 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-04-15-22-07-36.gh-issue-90622.0C6l8h.rst diff --git a/Lib/concurrent/futures/process.py b/Lib/concurrent/futures/process.py index c03187de85a91c..57941e485d81c0 100644 --- a/Lib/concurrent/futures/process.py +++ b/Lib/concurrent/futures/process.py @@ -615,6 +615,10 @@ def __init__(self, max_workers=None, mp_context=None, mp_context = mp.get_context() self._mp_context = mp_context + # https://github.com/python/cpython/issues/90622 + self._safe_to_dynamically_spawn_children = ( + self._mp_context.get_start_method(allow_none=False) != "fork") + if initializer is not None and not callable(initializer): raise TypeError("initializer must be a callable") self._initializer = initializer @@ -665,6 +669,8 @@ def __init__(self, max_workers=None, mp_context=None, def _start_executor_manager_thread(self): if self._executor_manager_thread is None: # Start the processes so that their sentinels are known. + if not self._safe_to_dynamically_spawn_children: # ie, using fork. + self._launch_processes() self._executor_manager_thread = _ExecutorManagerThread(self) self._executor_manager_thread.start() _threads_wakeups[self._executor_manager_thread] = \ @@ -677,14 +683,31 @@ def _adjust_process_count(self): process_count = len(self._processes) if process_count < self._max_workers: - p = self._mp_context.Process( - target=_process_worker, - args=(self._call_queue, - self._result_queue, - self._initializer, - self._initargs)) - p.start() - self._processes[p.pid] = p + # Assertion disabled as this codepath is also used to replace a + # worker that unexpectedly dies, even when using the 'fork' start + # method. That means there is still a potential deadlock bug. If a + # 'fork' mp_context worker dies, we'll be forking a new one when + # we know a thread is running (self._executor_manager_thread). + #assert self._safe_to_dynamically_spawn_children or not self._executor_manager_thread, 'https://github.com/python/cpython/issues/90622' + self._spawn_process() + + def _launch_processes(self): + # https://github.com/python/cpython/issues/90622 + assert not self._executor_manager_thread, ( + 'Processes cannot be fork()ed after the thread has started, ' + 'deadlock in the child processes could result.') + for _ in range(len(self._processes), self._max_workers): + self._spawn_process() + + def _spawn_process(self): + p = self._mp_context.Process( + target=_process_worker, + args=(self._call_queue, + self._result_queue, + self._initializer, + self._initargs)) + p.start() + self._processes[p.pid] = p def submit(self, fn, /, *args, **kwargs): with self._shutdown_lock: @@ -705,7 +728,8 @@ def submit(self, fn, /, *args, **kwargs): # Wake up queue management thread self._executor_manager_thread_wakeup.wakeup() - self._adjust_process_count() + if self._safe_to_dynamically_spawn_children: + self._adjust_process_count() self._start_executor_manager_thread() return f submit.__doc__ = _base.Executor.submit.__doc__ diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index d3d912892cc2d5..d8e091979aee3d 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -498,10 +498,16 @@ def acquire_lock(lock): lock.acquire() mp_context = self.get_context() + if mp_context.get_start_method(allow_none=False) == "fork": + # fork pre-spawns, not on demand. + expected_num_processes = self.worker_count + else: + expected_num_processes = 3 + sem = mp_context.Semaphore(0) for _ in range(3): self.executor.submit(acquire_lock, sem) - self.assertEqual(len(self.executor._processes), 3) + self.assertEqual(len(self.executor._processes), expected_num_processes) for _ in range(3): sem.release() processes = self.executor._processes @@ -1022,6 +1028,8 @@ def test_saturation(self): def test_idle_process_reuse_one(self): executor = self.executor assert executor._max_workers >= 4 + if self.get_context().get_start_method(allow_none=False) == "fork": + raise unittest.SkipTest("Incompatible with the fork start method.") executor.submit(mul, 21, 2).result() executor.submit(mul, 6, 7).result() executor.submit(mul, 3, 14).result() @@ -1030,6 +1038,8 @@ def test_idle_process_reuse_one(self): def test_idle_process_reuse_multiple(self): executor = self.executor assert executor._max_workers <= 5 + if self.get_context().get_start_method(allow_none=False) == "fork": + raise unittest.SkipTest("Incompatible with the fork start method.") executor.submit(mul, 12, 7).result() executor.submit(mul, 33, 25) executor.submit(mul, 25, 26).result() diff --git a/Misc/NEWS.d/next/Library/2022-04-15-22-07-36.gh-issue-90622.0C6l8h.rst b/Misc/NEWS.d/next/Library/2022-04-15-22-07-36.gh-issue-90622.0C6l8h.rst new file mode 100644 index 00000000000000..5db0a1bbe721df --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-15-22-07-36.gh-issue-90622.0C6l8h.rst @@ -0,0 +1,4 @@ +Worker processes for :class:`concurrent.futures.ProcessPoolExecutor` are no +longer spawned on demand (a feature added in 3.9) when the multiprocessing +context start method is ``"fork"`` as that can lead to deadlocks in the +child processes due to a fork happening while threads are running. From 8883172893b6c3bb553cd22fc351e0206dec8388 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Sun, 8 May 2022 19:32:54 +0200 Subject: [PATCH 163/237] Fix use of the default role in a news entry. (#92500) --- .../Documentation/2022-04-24-22-09-31.gh-issue-91888.kTjJLx.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Documentation/2022-04-24-22-09-31.gh-issue-91888.kTjJLx.rst b/Misc/NEWS.d/next/Documentation/2022-04-24-22-09-31.gh-issue-91888.kTjJLx.rst index 9194be9dbf92df..4ebca42a7fec5b 100644 --- a/Misc/NEWS.d/next/Documentation/2022-04-24-22-09-31.gh-issue-91888.kTjJLx.rst +++ b/Misc/NEWS.d/next/Documentation/2022-04-24-22-09-31.gh-issue-91888.kTjJLx.rst @@ -1 +1 @@ -Add a new `gh` role to the documentation to link to GitHub issues. +Add a new ``gh`` role to the documentation to link to GitHub issues. From ca425ac11a152c51f84d3eba0e133f21eb67f07e Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 8 May 2022 12:46:18 -0700 Subject: [PATCH 164/237] gh-77521: Add link to builtin module names in modules tutorial (GH-92438) Co-authored-by: Jelle Zijlstra (cherry picked from commit 859250cc55711f4d62b65922d3f7537826c3801e) Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> --- Doc/tutorial/modules.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst index 47c1f1877d6967..83d7a4b277b8a8 100644 --- a/Doc/tutorial/modules.rst +++ b/Doc/tutorial/modules.rst @@ -183,7 +183,8 @@ The Module Search Path .. index:: triple: module; search; path When a module named :mod:`spam` is imported, the interpreter first searches for -a built-in module with that name. If not found, it then searches for a file +a built-in module with that name. These module names are listed in +:data:`sys.builtin_module_names`. If not found, it then searches for a file named :file:`spam.py` in a list of directories given by the variable :data:`sys.path`. :data:`sys.path` is initialized from these locations: From 6679fdf4f0dbfb35d10c26343900ece18fef2856 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 8 May 2022 16:38:47 -0700 Subject: [PATCH 165/237] pdb docs: workaround for double semicolon in strings (GH-17011) see https://github.com/gotcha/ipdb/issues/172 Co-authored-by: Jelle Zijlstra (cherry picked from commit 2888b1107fd0b43cc800987a00155bdbeacdb23a) Co-authored-by: Godefroid Chapelle --- Doc/library/pdb.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index 13e1a1993692d4..dcd509de56adc4 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -233,7 +233,8 @@ Multiple commands may be entered on a single line, separated by ``;;``. (A single ``;`` is not used as it is the separator for multiple commands in a line that is passed to the Python parser.) No intelligence is applied to separating the commands; the input is split at the first ``;;`` pair, even if it is in the -middle of a quoted string. +middle of a quoted string. A workaround for strings with double semicolons +is to use implicit string concatenation ``';'';'`` or ``";"";"``. .. index:: pair: .pdbrc; file From 158579654ded615f0f9fa13d674b06473f7b1620 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 8 May 2022 16:39:09 -0700 Subject: [PATCH 166/237] bpo-39229: fix formatting in library/functions.rst (GH-17857) Missing reference of auditing event presents error when building translated documentation (cherry picked from commit f298ba1f2712ad10530a30bb225548a6889820b5) Co-authored-by: Rafael Fontenelle --- Doc/library/functions.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index ff81558da14cf8..85e7d12ceb91fe 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -846,8 +846,8 @@ are always available. They are listed here in alphabetical order. .. audit-event:: builtins.input/result result input - Raises an auditing event ``builtins.input/result`` with the result after - successfully reading input. + Raises an :ref:`auditing event ` ``builtins.input/result`` + with the result after successfully reading input. .. class:: int([x]) From cd110687126d9f19da42d8eb2404032e994ef28b Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 8 May 2022 20:16:26 -0700 Subject: [PATCH 167/237] bpo-38056: overhaul Error Handlers section in codecs documentation (GH-15732) * Some handlers were wrongly described as text-encoding only, but actually they can also be used in text-decoding. * Add more description to each handler. * Add two REPL examples. * Add indexes for Error Handler's name. Co-authored-by: Kyle Stanley Co-authored-by: Victor Stinner Co-authored-by: Jelle Zijlstra (cherry picked from commit 5bc2390229bbcb4f13359e867fd8a140a1d5496b) Co-authored-by: Ma Lin --- Doc/glossary.rst | 11 +- Doc/library/codecs.rst | 189 +++++++++++------- .../2019-09-12-08-28-17.bpo-38056.6ktYkc.rst | 1 + 3 files changed, 127 insertions(+), 74 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2019-09-12-08-28-17.bpo-38056.6ktYkc.rst diff --git a/Doc/glossary.rst b/Doc/glossary.rst index ddf085b8c1a6c6..62c9b867ca12e3 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -1136,7 +1136,16 @@ Glossary See also :term:`borrowed reference`. text encoding - A codec which encodes Unicode strings to bytes. + A string in Python is a sequence of Unicode code points (in range + ``U+0000``--``U+10FFFF``). To store or transfer a string, it needs to be + serialized as a sequence of bytes. + + Serializing a string into a sequence of bytes is known as "encoding", and + recreating the string from the sequence of bytes is known as "decoding". + + There are a variety of different text serialization + :ref:`codecs `, which are collectively referred to as + "text encodings". text file A :term:`file object` able to read and write :class:`str` objects. diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst index 73fbefccd728ae..1c10462c1509c3 100644 --- a/Doc/library/codecs.rst +++ b/Doc/library/codecs.rst @@ -23,11 +23,11 @@ This module defines base classes for standard Python codecs (encoders and decoders) and provides access to the internal Python codec registry, which manages the codec and error handling lookup process. Most standard codecs -are :term:`text encodings `, which encode text to bytes, -but there are also codecs provided that encode text to text, and bytes to -bytes. Custom codecs may encode and decode between arbitrary types, but some -module features are restricted to use specifically with -:term:`text encodings `, or with codecs that encode to +are :term:`text encodings `, which encode text to bytes (and +decode bytes to text), but there are also codecs provided that encode text to +text, and bytes to bytes. Custom codecs may encode and decode between arbitrary +types, but some module features are restricted to be used specifically with +:term:`text encodings ` or with codecs that encode to :class:`bytes`. The module defines the following functions for encoding and decoding with @@ -297,58 +297,56 @@ codec will handle encoding and decoding errors. Error Handlers ^^^^^^^^^^^^^^ -To simplify and standardize error handling, -codecs may implement different error handling schemes by -accepting the *errors* string argument. The following string values are -defined and implemented by all standard Python codecs: +To simplify and standardize error handling, codecs may implement different +error handling schemes by accepting the *errors* string argument: -.. tabularcolumns:: |l|L| - -+-------------------------+-----------------------------------------------+ -| Value | Meaning | -+=========================+===============================================+ -| ``'strict'`` | Raise :exc:`UnicodeError` (or a subclass); | -| | this is the default. Implemented in | -| | :func:`strict_errors`. | -+-------------------------+-----------------------------------------------+ -| ``'ignore'`` | Ignore the malformed data and continue | -| | without further notice. Implemented in | -| | :func:`ignore_errors`. | -+-------------------------+-----------------------------------------------+ - -The following error handlers are only applicable to -:term:`text encodings `: + >>> 'German ß, ♬'.encode(encoding='ascii', errors='backslashreplace') + b'German \\xdf, \\u266c' + >>> 'German ß, ♬'.encode(encoding='ascii', errors='xmlcharrefreplace') + b'German ß, ♬' .. index:: + pair: strict; error handler's name + pair: ignore; error handler's name + pair: replace; error handler's name + pair: backslashreplace; error handler's name + pair: surrogateescape; error handler's name single: ? (question mark); replacement character single: \ (backslash); escape sequence single: \x; escape sequence single: \u; escape sequence single: \U; escape sequence - single: \N; escape sequence + +The following error handlers can be used with all Python +:ref:`standard-encodings` codecs: + +.. tabularcolumns:: |l|L| +-------------------------+-----------------------------------------------+ | Value | Meaning | +=========================+===============================================+ -| ``'replace'`` | Replace with a suitable replacement | -| | marker; Python will use the official | -| | ``U+FFFD`` REPLACEMENT CHARACTER for the | -| | built-in codecs on decoding, and '?' on | -| | encoding. Implemented in | -| | :func:`replace_errors`. | +| ``'strict'`` | Raise :exc:`UnicodeError` (or a subclass), | +| | this is the default. Implemented in | +| | :func:`strict_errors`. | +-------------------------+-----------------------------------------------+ -| ``'xmlcharrefreplace'`` | Replace with the appropriate XML character | -| | reference (only for encoding). Implemented | -| | in :func:`xmlcharrefreplace_errors`. | +| ``'ignore'`` | Ignore the malformed data and continue without| +| | further notice. Implemented in | +| | :func:`ignore_errors`. | ++-------------------------+-----------------------------------------------+ +| ``'replace'`` | Replace with a replacement marker. On | +| | encoding, use ``?`` (ASCII character). On | +| | decoding, use ``�`` (U+FFFD, the official | +| | REPLACEMENT CHARACTER). Implemented in | +| | :func:`replace_errors`. | +-------------------------+-----------------------------------------------+ | ``'backslashreplace'`` | Replace with backslashed escape sequences. | +| | On encoding, use hexadecimal form of Unicode | +| | code point with formats ``\xhh`` ``\uxxxx`` | +| | ``\Uxxxxxxxx``. On decoding, use hexadecimal | +| | form of byte value with format ``\xhh``. | | | Implemented in | | | :func:`backslashreplace_errors`. | +-------------------------+-----------------------------------------------+ -| ``'namereplace'`` | Replace with ``\N{...}`` escape sequences | -| | (only for encoding). Implemented in | -| | :func:`namereplace_errors`. | -+-------------------------+-----------------------------------------------+ | ``'surrogateescape'`` | On decoding, replace byte with individual | | | surrogate code ranging from ``U+DC80`` to | | | ``U+DCFF``. This code will then be turned | @@ -358,27 +356,55 @@ The following error handlers are only applicable to | | more.) | +-------------------------+-----------------------------------------------+ +.. index:: + pair: xmlcharrefreplace; error handler's name + pair: namereplace; error handler's name + single: \N; escape sequence + +The following error handlers are only applicable to encoding (within +:term:`text encodings `): + ++-------------------------+-----------------------------------------------+ +| Value | Meaning | ++=========================+===============================================+ +| ``'xmlcharrefreplace'`` | Replace with XML/HTML numeric character | +| | reference, which is a decimal form of Unicode | +| | code point with format ``&#num;`` Implemented | +| | in :func:`xmlcharrefreplace_errors`. | ++-------------------------+-----------------------------------------------+ +| ``'namereplace'`` | Replace with ``\N{...}`` escape sequences, | +| | what appears in the braces is the Name | +| | property from Unicode Character Database. | +| | Implemented in :func:`namereplace_errors`. | ++-------------------------+-----------------------------------------------+ + +.. index:: + pair: surrogatepass; error handler's name + In addition, the following error handler is specific to the given codecs: +-------------------+------------------------+-------------------------------------------+ | Value | Codecs | Meaning | +===================+========================+===========================================+ -|``'surrogatepass'``| utf-8, utf-16, utf-32, | Allow encoding and decoding of surrogate | -| | utf-16-be, utf-16-le, | codes. These codecs normally treat the | -| | utf-32-be, utf-32-le | presence of surrogates as an error. | +|``'surrogatepass'``| utf-8, utf-16, utf-32, | Allow encoding and decoding surrogate code| +| | utf-16-be, utf-16-le, | point (``U+D800`` - ``U+DFFF``) as normal | +| | utf-32-be, utf-32-le | code point. Otherwise these codecs treat | +| | | the presence of surrogate code point in | +| | | :class:`str` as an error. | +-------------------+------------------------+-------------------------------------------+ .. versionadded:: 3.1 The ``'surrogateescape'`` and ``'surrogatepass'`` error handlers. .. versionchanged:: 3.4 - The ``'surrogatepass'`` error handlers now works with utf-16\* and utf-32\* codecs. + The ``'surrogatepass'`` error handler now works with utf-16\* and utf-32\* + codecs. .. versionadded:: 3.5 The ``'namereplace'`` error handler. .. versionchanged:: 3.5 - The ``'backslashreplace'`` error handlers now works with decoding and + The ``'backslashreplace'`` error handler now works with decoding and translating. The set of allowed values can be extended by registering a new named error @@ -421,42 +447,59 @@ functions: .. function:: strict_errors(exception) - Implements the ``'strict'`` error handling: each encoding or - decoding error raises a :exc:`UnicodeError`. + Implements the ``'strict'`` error handling. + Each encoding or decoding error raises a :exc:`UnicodeError`. -.. function:: replace_errors(exception) - Implements the ``'replace'`` error handling (for :term:`text encodings - ` only): substitutes ``'?'`` for encoding errors - (to be encoded by the codec), and ``'\ufffd'`` (the Unicode replacement - character) for decoding errors. +.. function:: ignore_errors(exception) + Implements the ``'ignore'`` error handling. -.. function:: ignore_errors(exception) + Malformed data is ignored; encoding or decoding is continued without + further notice. - Implements the ``'ignore'`` error handling: malformed data is ignored and - encoding or decoding is continued without further notice. +.. function:: replace_errors(exception) -.. function:: xmlcharrefreplace_errors(exception) + Implements the ``'replace'`` error handling. - Implements the ``'xmlcharrefreplace'`` error handling (for encoding with - :term:`text encodings ` only): the - unencodable character is replaced by an appropriate XML character reference. + Substitutes ``?`` (ASCII character) for encoding errors or ``�`` (U+FFFD, + the official REPLACEMENT CHARACTER) for decoding errors. .. function:: backslashreplace_errors(exception) - Implements the ``'backslashreplace'`` error handling (for - :term:`text encodings ` only): malformed data is - replaced by a backslashed escape sequence. + Implements the ``'backslashreplace'`` error handling. + + Malformed data is replaced by a backslashed escape sequence. + On encoding, use the hexadecimal form of Unicode code point with formats + ``\xhh`` ``\uxxxx`` ``\Uxxxxxxxx``. On decoding, use the hexadecimal form of + byte value with format ``\xhh``. + + .. versionchanged:: 3.5 + Works with decoding and translating. + + +.. function:: xmlcharrefreplace_errors(exception) + + Implements the ``'xmlcharrefreplace'`` error handling (for encoding within + :term:`text encoding` only). + + The unencodable character is replaced by an appropriate XML/HTML numeric + character reference, which is a decimal form of Unicode code point with + format ``&#num;`` . + .. function:: namereplace_errors(exception) - Implements the ``'namereplace'`` error handling (for encoding with - :term:`text encodings ` only): the - unencodable character is replaced by a ``\N{...}`` escape sequence. + Implements the ``'namereplace'`` error handling (for encoding within + :term:`text encoding` only). + + The unencodable character is replaced by a ``\N{...}`` escape sequence. The + set of characters that appear in the braces is the Name property from + Unicode Character Database. For example, the German lowercase letter ``'ß'`` + will be converted to byte sequence ``\N{LATIN SMALL LETTER SHARP S}`` . .. versionadded:: 3.5 @@ -470,7 +513,7 @@ The base :class:`Codec` class defines these methods which also define the function interfaces of the stateless encoder and decoder: -.. method:: Codec.encode(input[, errors]) +.. method:: Codec.encode(input, errors='strict') Encodes the object *input* and returns a tuple (output object, length consumed). For instance, :term:`text encoding` converts @@ -488,7 +531,7 @@ function interfaces of the stateless encoder and decoder: of the output object type in this situation. -.. method:: Codec.decode(input[, errors]) +.. method:: Codec.decode(input, errors='strict') Decodes the object *input* and returns a tuple (output object, length consumed). For instance, for a :term:`text encoding`, decoding converts @@ -555,7 +598,7 @@ define in order to be compatible with the Python codec registry. object. - .. method:: encode(object[, final]) + .. method:: encode(object, final=False) Encodes *object* (taking the current state of the encoder into account) and returns the resulting encoded object. If this is the last call to @@ -612,7 +655,7 @@ define in order to be compatible with the Python codec registry. object. - .. method:: decode(object[, final]) + .. method:: decode(object, final=False) Decodes *object* (taking the current state of the decoder into account) and returns the resulting decoded object. If this is the last call to @@ -746,7 +789,7 @@ compatible with the Python codec registry. :func:`register_error`. - .. method:: read([size[, chars, [firstline]]]) + .. method:: read(size=-1, chars=-1, firstline=False) Decodes data from the stream and returns the resulting object. @@ -772,7 +815,7 @@ compatible with the Python codec registry. available on the stream, these should be read too. - .. method:: readline([size[, keepends]]) + .. method:: readline(size=None, keepends=True) Read one line from the input stream and return the decoded data. @@ -783,7 +826,7 @@ compatible with the Python codec registry. returned. - .. method:: readlines([sizehint[, keepends]]) + .. method:: readlines(sizehint=None, keepends=True) Read all lines available on the input stream and return them as a list of lines. @@ -874,7 +917,7 @@ Encodings and Unicode --------------------- Strings are stored internally as sequences of code points in -range ``0x0``--``0x10FFFF``. (See :pep:`393` for +range ``U+0000``--``U+10FFFF``. (See :pep:`393` for more details about the implementation.) Once a string object is used outside of CPU and memory, endianness and how these arrays are stored as bytes become an issue. As with other @@ -955,7 +998,7 @@ encoding was used for encoding a string. Each charmap encoding can decode any random byte sequence. However that's not possible with UTF-8, as UTF-8 byte sequences have a structure that doesn't allow arbitrary byte sequences. To increase the reliability with which a UTF-8 encoding can be -detected, Microsoft invented a variant of UTF-8 (that Python 2.5 calls +detected, Microsoft invented a variant of UTF-8 (that Python calls ``"utf-8-sig"``) for its Notepad program: Before any of the Unicode characters is written to the file, a UTF-8 encoded BOM (which looks like this as a byte sequence: ``0xef``, ``0xbb``, ``0xbf``) is written. As it's rather improbable diff --git a/Misc/NEWS.d/next/Documentation/2019-09-12-08-28-17.bpo-38056.6ktYkc.rst b/Misc/NEWS.d/next/Documentation/2019-09-12-08-28-17.bpo-38056.6ktYkc.rst new file mode 100644 index 00000000000000..2e6b70fd84b6d9 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-09-12-08-28-17.bpo-38056.6ktYkc.rst @@ -0,0 +1 @@ +Overhaul the :ref:`error-handlers` documentation in :mod:`codecs`. From eded1036f14aeb30c697a4ad1bf58247bd985fc6 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 9 May 2022 01:27:00 -0700 Subject: [PATCH 168/237] CODEOWNERS: Add Erlend Aasland as sqlite3 code owner (GH-92535) Signed-off-by: Erlend E. Aasland (cherry picked from commit 3edda031e4abcdc8a2974f2708db99eeb109de32) Co-authored-by: Erlend Egeberg Aasland --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9a5bc639247883..173b957b108c60 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -96,7 +96,7 @@ Lib/ast.py @isidentical /Lib/unittest/test/testmock/* @cjw296 # SQLite 3 -**/*sqlite* @berkerpeksag +**/*sqlite* @berkerpeksag @erlend-aasland # subprocess /Lib/subprocess.py @gpshead From 826ceab4884c667ca69ee222af1b6dcf1d49b91d Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 9 May 2022 14:28:40 -0700 Subject: [PATCH 169/237] Doc: Update py2app link. (GH-91585) See: https://mail.python.org/archives/list/docs@python.org/thread/KDVFGNGGUGGPVRZT7WZYHHWXCRS2GEN7/ (cherry picked from commit b77a95f44a024d1afab28e380252aa6d9c4efb1c) Co-authored-by: Julien Palard --- Doc/using/mac.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/using/mac.rst b/Doc/using/mac.rst index 2f132a96bef082..f7db038430b6d3 100644 --- a/Doc/using/mac.rst +++ b/Doc/using/mac.rst @@ -160,7 +160,7 @@ Distributing Python Applications on the Mac The standard tool for deploying standalone Python applications on the Mac is :program:`py2app`. More information on installing and using py2app can be found -at http://undefined.org/python/#py2app. +at https://pypi.org/project/py2app/. Other Resources From 5ed2f11834ca55cfeb405540401050cff9d36aa7 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 9 May 2022 21:27:37 -0700 Subject: [PATCH 170/237] bpo-13553: Document tkinter.Tk args (GH-4786) (cherry picked from commit c56e2bb9949c95ec8911cd5554b07044a564796f) Co-authored-by: Cheryl Sabella --- Doc/library/tkinter.rst | 76 ++++++++++++++++--- Lib/tkinter/__init__.py | 8 +- .../2017-12-10-19-13-39.bpo-13553.gQbZs4.rst | 1 + 3 files changed, 71 insertions(+), 14 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2017-12-10-19-13-39.bpo-13553.gQbZs4.rst diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 65395d824cab76..37b6a02a31710e 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -124,16 +124,72 @@ the modern themed widget set and API:: from tkinter import ttk -.. class:: Tk(screenName=None, baseName=None, className='Tk', useTk=1) - - The :class:`Tk` class is instantiated without arguments. This creates a toplevel - widget of Tk which usually is the main window of an application. Each instance - has its own associated Tcl interpreter. - - .. FIXME: The following keyword arguments are currently recognized: - - -.. function:: Tcl(screenName=None, baseName=None, className='Tk', useTk=0) +.. class:: Tk(screenName=None, baseName=None, className='Tk', useTk=True, sync=False, use=None) + + Construct a toplevel Tk widget, which is usually the main window of an + application, and initialize a Tcl interpreter for this widget. Each + instance has its own associated Tcl interpreter. + + The :class:`Tk` class is typically instantiated using all default values. + However, the following keyword arguments are currently recognized: + + *screenName* + When given (as a string), sets the :envvar:`DISPLAY` environment + variable. (X11 only) + *baseName* + Name of the profile file. By default, *baseName* is derived from the + program name (``sys.argv[0]``). + *className* + Name of the widget class. Used as a profile file and also as the name + with which Tcl is invoked (*argv0* in *interp*). + *useTk* + If ``True``, initialize the Tk subsystem. The :func:`tkinter.Tcl() ` + function sets this to ``False``. + *sync* + If ``True``, execute all X server commands synchronously, so that errors + are reported immediately. Can be used for debugging. (X11 only) + *use* + Specifies the *id* of the window in which to embed the application, + instead of it being created as an independent toplevel window. *id* must + be specified in the same way as the value for the -use option for + toplevel widgets (that is, it has a form like that returned by + :meth:`winfo_id`). + + Note that on some platforms this will only work correctly if *id* refers + to a Tk frame or toplevel that has its -container option enabled. + + :class:`Tk` reads and interprets profile files, named + :file:`.{className}.tcl` and :file:`.{baseName}.tcl`, into the Tcl + interpreter and calls :func:`exec` on the contents of + :file:`.{className}.py` and :file:`.{baseName}.py`. The path for the + profile files is the :envvar:`HOME` environment variable or, if that + isn't defined, then :attr:`os.curdir`. + + .. attribute:: tk + + The Tk application object created by instantiating :class:`Tk`. This + provides access to the Tcl interpreter. Each widget that is attached + the same instance of :class:`Tk` has the same value for its :attr:`tk` + attribute. + + .. attribute:: master + + The widget object that contains this widget. For :class:`Tk`, the + *master* is :const:`None` because it is the main window. The terms + *master* and *parent* are similar and sometimes used interchangeably + as argument names; however, calling :meth:`winfo_parent` returns a + string of the widget name whereas :attr:`master` returns the object. + *parent*/*child* reflects the tree-like relationship while + *master*/*slave* reflects the container structure. + + .. attribute:: children + + The immediate descendants of this widget as a :class:`dict` with the + child widget names as the keys and the child instance objects as the + values. + + +.. function:: Tcl(screenName=None, baseName=None, className='Tk', useTk=False) The :func:`Tcl` function is a factory function which creates an object much like that created by the :class:`Tk` class, except that it does not initialize the Tk diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index fa88448a2c071d..b20c16d6c8f392 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -2099,7 +2099,7 @@ def wm_iconbitmap(self, bitmap=None, default=None): the bitmap if None is given. Under Windows, the DEFAULT parameter can be used to set the icon - for the widget and any descendents that don't have an icon set + for the widget and any descendants that don't have an icon set explicitly. DEFAULT can be the relative path to a .ico file (example: root.iconbitmap(default='myicon.ico') ). See Tk documentation for more information.""" @@ -2345,9 +2345,9 @@ def destroy(self): _default_root = None def readprofile(self, baseName, className): - """Internal function. It reads BASENAME.tcl and CLASSNAME.tcl into - the Tcl Interpreter and calls exec on the contents of BASENAME.py and - CLASSNAME.py if such a file exists in the home directory.""" + """Internal function. It reads .BASENAME.tcl and .CLASSNAME.tcl into + the Tcl Interpreter and calls exec on the contents of .BASENAME.py and + .CLASSNAME.py if such a file exists in the home directory.""" import os if 'HOME' in os.environ: home = os.environ['HOME'] else: home = os.curdir diff --git a/Misc/NEWS.d/next/Documentation/2017-12-10-19-13-39.bpo-13553.gQbZs4.rst b/Misc/NEWS.d/next/Documentation/2017-12-10-19-13-39.bpo-13553.gQbZs4.rst new file mode 100644 index 00000000000000..23d3c1555e3707 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2017-12-10-19-13-39.bpo-13553.gQbZs4.rst @@ -0,0 +1 @@ +Document tkinter.Tk args. From 7954b664d4c5db56ec28da57e783186f4d713517 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 10 May 2022 00:43:26 -0700 Subject: [PATCH 171/237] gh-92256: Improve Argument Clinic parser error messages (GH-92268) Co-authored-by: Serhiy Storchaka Co-authored-by: Victor Stinner (cherry picked from commit 4bd07d1dbd493fc9b2c2a77e9e905c517682052e) Co-authored-by: Erlend Egeberg Aasland --- Tools/clinic/clinic.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index b442c494d31d49..9ea2784085aaca 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -1566,10 +1566,16 @@ def parse_clinic_block(self, dsl_name): def is_stop_line(line): # make sure to recognize stop line even if it # doesn't end with EOL (it could be the very end of the file) - if not line.startswith(stop_line): + if line.startswith(stop_line): + remainder = line[len(stop_line):] + if remainder and not remainder.isspace(): + fail(f"Garbage after stop line: {remainder!r}") + return True + else: + # gh-92256: don't allow incorrectly formatted stop lines + if line.lstrip().startswith(stop_line): + fail(f"Whitespace is not allowed before the stop line: {line!r}") return False - remainder = line[len(stop_line):] - return (not remainder) or remainder.isspace() # consume body of program while self.input: From dd0e8a62df8be2a09ef6035b4c92bd9a68a7b918 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 10 May 2022 02:28:22 -0700 Subject: [PATCH 172/237] [3.10] gh-76773: Update docs mentioning no-longer-supported Windows versions & features (GH-92529) (GH-92609) (cherry picked from commit f1bbcba74f77eff2a4c0881f3d529f3bf0664d40) Co-authored-by: CAM Gerlach Automerge-Triggered-By: GH:serhiy-storchaka --- Doc/extending/windows.rst | 4 +- Doc/faq/windows.rst | 8 +-- Doc/library/ctypes.rst | 7 +- Doc/library/optparse.rst | 2 +- Doc/library/os.path.rst | 2 +- Doc/library/tempfile.rst | 2 +- Doc/using/windows.rst | 134 +++++++++++++++----------------------- PC/readme.txt | 6 +- PCbuild/readme.txt | 20 +++--- 9 files changed, 70 insertions(+), 115 deletions(-) diff --git a/Doc/extending/windows.rst b/Doc/extending/windows.rst index c7b92c6ea24ca8..28d0350f6f114d 100644 --- a/Doc/extending/windows.rst +++ b/Doc/extending/windows.rst @@ -106,8 +106,7 @@ Using DLLs in Practice Windows Python is built in Microsoft Visual C++; using other compilers may or -may not work (though Borland seems to). The rest of this section is MSVC++ -specific. +may not work. The rest of this section is MSVC++ specific. When creating DLLs in Windows, you must pass :file:`pythonXY.lib` to the linker. To build two DLLs, spam and ni (which uses C functions found in spam), you could @@ -134,4 +133,3 @@ Developer Studio will throw in a lot of import libraries that you do not really need, adding about 100K to your executable. To get rid of them, use the Project Settings dialog, Link tab, to specify *ignore default libraries*. Add the correct :file:`msvcrtxx.lib` to the list of libraries. - diff --git a/Doc/faq/windows.rst b/Doc/faq/windows.rst index 0153a4f316ee82..4f50b3f1b93f1a 100644 --- a/Doc/faq/windows.rst +++ b/Doc/faq/windows.rst @@ -26,8 +26,8 @@ with running programs from the Windows command line then everything will seem obvious; otherwise, you might need a little more guidance. Unless you use some sort of integrated development environment, you will end up -*typing* Windows commands into what is variously referred to as a "DOS window" -or "Command prompt window". Usually you can create such a window from your +*typing* Windows commands into what is referred to as a +"Command prompt window". Usually you can create such a window from your search bar by searching for ``cmd``. You should be able to recognize when you have started such a window because you will see a Windows "command prompt", which usually looks like this: @@ -186,9 +186,6 @@ Embedding the Python interpreter in a Windows app can be summarized as follows: by the Windows ``GetProcAddress()`` routine. Macros can make using these pointers transparent to any C code that calls routines in Python's C API. - Borland note: convert :file:`python{NN}.lib` to OMF format using Coff2Omf.exe - first. - .. XXX what about static linking? 2. If you use SWIG, it is easy to create a Python "extension module" that will @@ -279,4 +276,3 @@ How do I check for a keypress without blocking? Use the :mod:`msvcrt` module. This is a standard Windows-specific extension module. It defines a function ``kbhit()`` which checks whether a keyboard hit is present, and ``getch()`` which gets one character without echoing it. - diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 7665f214916db0..19ce19b1d70d1d 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -1361,10 +1361,6 @@ way is to instantiate one of the following classes: functions in these libraries use the ``stdcall`` calling convention, and are assumed to return :c:type:`int` by default. - On Windows CE only the standard calling convention is used, for convenience the - :class:`WinDLL` and :class:`OleDLL` use the standard calling convention on this - platform. - The Python :term:`global interpreter lock` is released before calling any function exported by these libraries, and reacquired afterwards. @@ -1665,8 +1661,7 @@ See :ref:`ctypes-callback-functions` for examples. .. function:: WINFUNCTYPE(restype, *argtypes, use_errno=False, use_last_error=False) Windows only: The returned function prototype creates functions that use the - ``stdcall`` calling convention, except on Windows CE where - :func:`WINFUNCTYPE` is the same as :func:`CFUNCTYPE`. The function will + ``stdcall`` calling convention. The function will release the GIL during the call. *use_errno* and *use_last_error* have the same meaning as above. diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index b1094198f4c844..0d686b10365a6d 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -131,7 +131,7 @@ option These option syntaxes are not supported by :mod:`optparse`, and they never will be. This is deliberate: the first three are non-standard on any environment, and the last only makes sense if you're exclusively targeting - VMS, MS-DOS, and/or Windows. + Windows or certain legacy platforms (e.g. VMS, MS-DOS). option argument an argument that follows an option, is closely associated with that option, diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst index c201b1460ede30..ce7913e3712d73 100644 --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -5,7 +5,7 @@ :synopsis: Operations on pathnames. **Source code:** :source:`Lib/posixpath.py` (for POSIX) and -:source:`Lib/ntpath.py` (for Windows NT). +:source:`Lib/ntpath.py` (for Windows). .. index:: single: path; operations diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst index 30491d48e10ef0..f0f9f297461955 100644 --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -84,7 +84,7 @@ The module defines the following user-callable items: file-like object. Whether the name can be used to open the file a second time, while the named temporary file is still open, varies across platforms (it can be so used on Unix; it cannot - on Windows NT or later). If *delete* is true (the default), the file is + on Windows). If *delete* is true (the default), the file is deleted as soon as it is closed. The returned object is always a file-like object whose :attr:`!file` attribute is the underlying true file object. This file-like object can diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index 2c348aff12a624..87eb616d062491 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -374,7 +374,9 @@ may be changed from ``.``, and the package will be installed into a subdirectory. By default, the subdirectory is named the same as the package, and without the ``-ExcludeVersion`` option this name will include the specific version installed. Inside the subdirectory is a ``tools`` directory that -contains the Python installation:: +contains the Python installation: + +.. code-block:: doscon # Without -ExcludeVersion > .\python.3.5.2\tools\python.exe -V @@ -421,7 +423,7 @@ dependants, such as Idle), pip and the Python documentation are not included. .. note:: The embedded distribution does not include the `Microsoft C Runtime - `_ and it is + `_ and it is the responsibility of the application installer to provide this. The runtime may have already been installed on a user's system previously or automatically via Windows Update, and can be detected by finding @@ -555,27 +557,22 @@ System variables, you need non-restricted access to your machine Windows will concatenate User variables *after* System variables, which may cause unexpected results when modifying :envvar:`PATH`. - The :envvar:`PYTHONPATH` variable is used by all versions of Python 2 and - Python 3, so you should not permanently configure this variable unless it - only includes code that is compatible with all of your installed Python + The :envvar:`PYTHONPATH` variable is used by all versions of Python, + so you should not permanently configure it unless the listed paths + only include code that is compatible with all of your installed Python versions. .. seealso:: - https://www.microsoft.com/en-us/wdsi/help/folder-variables - Environment variables in Windows NT - - https://technet.microsoft.com/en-us/library/cc754250.aspx - The SET command, for temporarily modifying environment variables + https://docs.microsoft.com/en-us/windows/win32/procthread/environment-variables + Overview of environment variables on Windows - https://technet.microsoft.com/en-us/library/cc755104.aspx - The SETX command, for permanently modifying environment variables + https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/set_1 + The ``set`` command, for temporarily modifying environment variables - https://support.microsoft.com/en-us/help/310519/how-to-manage-environment-variables-in-windows-xp - How To Manage Environment Variables in Windows XP + https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/setx + The ``setx`` command, for permanently modifying environment variables - https://www.chem.gla.ac.uk/~louis/software/faq/q1.html - Setting Environment variables, Louis J. Farrugia .. _windows-path-mod: @@ -673,9 +670,7 @@ From the command-line System-wide installations of Python 3.3 and later will put the launcher on your :envvar:`PATH`. The launcher is compatible with all available versions of Python, so it does not matter which version is installed. To check that the -launcher is available, execute the following command in Command Prompt: - -:: +launcher is available, execute the following command in Command Prompt:: py @@ -683,26 +678,20 @@ You should find that the latest version of Python you have installed is started - it can be exited as normal, and any additional command-line arguments specified will be sent directly to Python. -If you have multiple versions of Python installed (e.g., 2.7 and |version|) you -will have noticed that Python |version| was started - to launch Python 2.7, try -the command: - -:: - - py -2.7 +If you have multiple versions of Python installed (e.g., 3.7 and |version|) you +will have noticed that Python |version| was started - to launch Python 3.7, try +the command:: -If you want the latest version of Python 2.x you have installed, try the -command: + py -3.7 -:: +If you want the latest version of Python 2 you have installed, try the +command:: py -2 -You should find the latest version of Python 2.x starts. +You should find the latest version of Python 3.x starts. -If you see the following error, you do not have the launcher installed: - -:: +If you see the following error, you do not have the launcher installed:: 'py' is not recognized as an internal or external command, operable program or batch file. @@ -710,11 +699,11 @@ If you see the following error, you do not have the launcher installed: Per-user installations of Python do not add the launcher to :envvar:`PATH` unless the option was selected on installation. -:: +The command:: py --list -You should see the currently installed versions of Python. +displays the currently installed version(s) of Python. Virtual environments ^^^^^^^^^^^^^^^^^^^^ @@ -740,9 +729,7 @@ following contents import sys sys.stdout.write("hello from Python %s\n" % (sys.version,)) -From the directory in which hello.py lives, execute the command: - -:: +From the directory in which hello.py lives, execute the command:: py hello.py @@ -755,9 +742,9 @@ is printed. Now try changing the first line to be: Re-executing the command should now print the latest Python 3.x information. As with the above command-line examples, you can specify a more explicit -version qualifier. Assuming you have Python 2.6 installed, try changing the -first line to ``#! python2.6`` and you should find the 2.6 version -information printed. +version qualifier. Assuming you have Python 3.7 installed, try changing +the first line to ``#! python3.7`` and you should find the |version| +version information printed. Note that unlike interactive use, a bare "python" will use the latest version of Python 2.x that you have installed. This is for backward @@ -810,8 +797,8 @@ shebang lines starting with ``/usr``. Any of the above virtual commands can be suffixed with an explicit version (either just the major version, or the major and minor version). Furthermore the 32-bit version can be requested by adding "-32" after the -minor version. I.e. ``/usr/bin/python2.7-32`` will request usage of the -32-bit python 2.7. +minor version. I.e. ``/usr/bin/python3.7-32`` will request usage of the +32-bit python 3.7. .. versionadded:: 3.7 @@ -897,19 +884,19 @@ Examples: ``python2`` will use the latest Python 2.x version installed and the command ``python3`` will use the latest Python 3.x installed. -* The commands ``python3.1`` and ``python2.7`` will not consult any +* The command ``python3.7`` will not consult any options at all as the versions are fully specified. * If ``PY_PYTHON=3``, the commands ``python`` and ``python3`` will both use the latest installed Python 3 version. -* If ``PY_PYTHON=3.1-32``, the command ``python`` will use the 32-bit - implementation of 3.1 whereas the command ``python3`` will use the latest +* If ``PY_PYTHON=3.7-32``, the command ``python`` will use the 32-bit + implementation of 3.7 whereas the command ``python3`` will use the latest installed Python (PY_PYTHON was not considered at all as a major version was specified.) -* If ``PY_PYTHON=3`` and ``PY_PYTHON3=3.1``, the commands - ``python`` and ``python3`` will both use specifically 3.1 +* If ``PY_PYTHON=3`` and ``PY_PYTHON3=3.7``, the commands + ``python`` and ``python3`` will both use specifically 3.7 In addition to environment variables, the same settings can be configured in the .INI file used by the launcher. The section in the INI file is @@ -920,21 +907,21 @@ an environment variable will override things specified in the INI file. For example: -* Setting ``PY_PYTHON=3.1`` is equivalent to the INI file containing: +* Setting ``PY_PYTHON=3.7`` is equivalent to the INI file containing: .. code-block:: ini [defaults] - python=3.1 + python=3.7 -* Setting ``PY_PYTHON=3`` and ``PY_PYTHON3=3.1`` is equivalent to the INI file +* Setting ``PY_PYTHON=3`` and ``PY_PYTHON3=3.7`` is equivalent to the INI file containing: .. code-block:: ini [defaults] python=3 - python3=3.1 + python3=3.7 Diagnostics ----------- @@ -1088,13 +1075,14 @@ is a collection of modules for advanced Windows-specific support. This includes utilities for: * `Component Object Model - `_ + `_ (COM) * Win32 API calls * Registry * Event log -* `Microsoft Foundation Classes `_ (MFC) - user interfaces +* `Microsoft Foundation Classes + `_ + (MFC) user interfaces `PythonWin `_ is a sample MFC application @@ -1105,7 +1093,7 @@ shipped with PyWin32. It is an embeddable IDE with a built-in debugger. `Win32 How Do I...? `_ by Tim Golden - `Python and COM `_ + `Python and COM `_ by David and Paul Boddie @@ -1119,18 +1107,6 @@ you can distribute your application without requiring your users to install Python. -WConio ------- - -Since Python's advanced terminal handling layer, :mod:`curses`, is restricted to -Unix-like systems, there is a library exclusive to Windows as well: Windows -Console I/O for Python. - -`WConio `_ is a wrapper for -Turbo-C's :file:`CONIO.H`, used to create text user interfaces. - - - Compiling Python on Windows =========================== @@ -1140,21 +1116,13 @@ latest release's source or just grab a fresh `checkout `_. The source tree contains a build solution and project files for Microsoft -Visual Studio 2015, which is the compiler used to build the official Python +Visual Studio, which is the compiler used to build the official Python releases. These files are in the :file:`PCbuild` directory. Check :file:`PCbuild/readme.txt` for general information on the build process. - For extension modules, consult :ref:`building-on-windows`. -.. seealso:: - - `Python + Windows + distutils + SWIG + gcc MinGW `_ - or "Creating Python extensions in C/C++ with SWIG and compiling them with - MinGW gcc under Windows" or "Installing Python extension with distutils - and without Microsoft Visual C++" by Sébastien Sauvage, 2003 - Other Platforms =============== @@ -1163,12 +1131,12 @@ With ongoing development of Python, some platforms that used to be supported earlier are no longer supported (due to the lack of users or developers). Check :pep:`11` for details on all unsupported platforms. -* `Windows CE `_ is still supported. -* The `Cygwin `_ installer offers to install the Python - interpreter as well (cf. `Cygwin package source - `_, `Maintainer releases - `_) +* `Windows CE `_ is + `no longer supported `__ + since Python 3 (if it ever was). +* The `Cygwin `_ installer offers to install the + `Python interpreter `__ + as well See `Python for Windows `_ for detailed information about platforms with pre-compiled installers. diff --git a/PC/readme.txt b/PC/readme.txt index 0a96d269b0977d..4e6dcf98c937f4 100644 --- a/PC/readme.txt +++ b/PC/readme.txt @@ -18,7 +18,7 @@ All PC ports use this scheme to try to set up a module search path: 1) The script location; the current directory without script. 2) The PYTHONPATH variable, if set. - 3) For Win32 platforms (NT/95), paths specified in the Registry. + 3) Paths specified in the Registry. 4) Default directories lib, lib/win, lib/test, lib/tkinter; these are searched relative to the environment variable PYTHONHOME, if set, or relative to the executable and its @@ -26,8 +26,8 @@ All PC ports use this scheme to try to set up a module search path: or the current directory (not useful). 5) The directory containing the executable. -The best installation strategy is to put the Python executable (and -DLL, for Win32 platforms) in some convenient directory such as +The best installation strategy is to put the Python executable and +DLL in some convenient directory such as C:/python, and copy all library files and subdirectories (using XCOPY) to C:/python/lib. Then you don't need to set PYTHONPATH. Otherwise, set the environment variable PYTHONPATH to your Python search path. diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index 1ea8bebc15edfe..76f421a9aaee2b 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -13,12 +13,10 @@ Quick Start Guide Building Python using Microsoft Visual C++ ------------------------------------------ -This directory is used to build CPython for Microsoft Windows NT version -6.0 or higher (Windows Vista, Windows Server 2008, or later) on 32 and 64 +This directory is used to build CPython for Microsoft Windows on 32- and 64- bit platforms. Using this directory requires an installation of -Microsoft Visual Studio 2017 (MSVC 14.1) with the *Python workload* and -its optional *Python native development* component selected. (For -command-line builds, Visual Studio 2015 may also be used.) +Microsoft Visual Studio (MSVC) with the *Python workload* and +its optional *Python native development* component selected. Building from the command line is recommended in order to obtain any external dependencies. To build, simply run the "build.bat" script without @@ -105,7 +103,7 @@ pythonw Prompt window pylauncher py.exe, the Python Launcher for Windows, see - http://docs.python.org/3/using/windows.html#launcher + https://docs.python.org/3/using/windows.html#launcher pywlauncher pyw.exe, a variant of py.exe that doesn't open a Command Prompt window @@ -167,14 +165,14 @@ _bz2 _lzma Python wrapper for version 5.2.2 of the liblzma compression library Homepage: - http://tukaani.org/xz/ + https://tukaani.org/xz/ _ssl Python wrapper for version 1.1.1k of the OpenSSL secure sockets library, which is downloaded from our binaries repository at https://github.com/python/cpython-bin-deps. Homepage: - http://www.openssl.org/ + https://www.openssl.org/ Building OpenSSL requires Perl on your path, and can be performed by running PCbuild\prepare_ssl.bat. This will retrieve the version of @@ -190,14 +188,14 @@ _ssl _sqlite3 Wraps SQLite 3.37.2, which is itself built by sqlite3.vcxproj Homepage: - http://www.sqlite.org/ + https://www.sqlite.org/ _tkinter Wraps version 8.6.6 of the Tk windowing system, which is downloaded from our binaries repository at https://github.com/python/cpython-bin-deps. Homepage: - http://www.tcl.tk/ + https://www.tcl.tk/ Building Tcl and Tk can be performed by running PCbuild\prepare_tcltk.bat. This will retrieve the version of the @@ -256,7 +254,7 @@ It creates the PGI files, runs the unit test suite or PyBench with the PGI python, and finally creates the optimized files. See - http://msdn.microsoft.com/en-us/library/e7k32f4k(VS.140).aspx + https://docs.microsoft.com/en-us/cpp/build/profile-guided-optimizations for more on this topic. From 9be9b585aac111becb5b95b053360ed9b7d206e0 Mon Sep 17 00:00:00 2001 From: Itai Steinherz Date: Wed, 11 May 2022 01:52:39 +0300 Subject: [PATCH 173/237] bpo-46785: Fix race condition between os.stat() and unlink on Windows (GH-31858) * [3.10] bpo-46785: Fix race condition between os.stat() and unlink on Windows (GH-31858). (cherry picked from commit 39e6b8ae6a5b49bb23746fdcc354d148ff2d98e3) Co-authored-by: Itai Steinherz --- Lib/test/test_os.py | 43 +++++++++++++++++++ Misc/ACKS | 1 + .../2022-03-13-20-35-41.bpo-46785.Pnknyl.rst | 1 + Modules/posixmodule.c | 12 +++++- 4 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Windows/2022-03-13-20-35-41.bpo-46785.Pnknyl.rst diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 7f7d14ef0a0951..1243b575dcafd1 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -23,6 +23,7 @@ import sys import sysconfig import tempfile +import textwrap import threading import time import types @@ -2859,6 +2860,48 @@ def test_getfinalpathname_handles(self): self.assertEqual(0, handle_delta) + def test_stat_unlink_race(self): + # bpo-46785: the implementation of os.stat() falls back to reading + # the parent directory if CreateFileW() fails with a permission + # error. If reading the parent directory fails because the file or + # directory are subsequently unlinked, or because the volume or + # share are no longer available, then the original permission error + # should not be restored. + filename = os_helper.TESTFN + self.addCleanup(os_helper.unlink, filename) + deadline = time.time() + 5 + command = textwrap.dedent("""\ + import os + import sys + import time + + filename = sys.argv[1] + deadline = float(sys.argv[2]) + + while time.time() < deadline: + try: + with open(filename, "w") as f: + pass + except OSError: + pass + try: + os.remove(filename) + except OSError: + pass + """) + + with subprocess.Popen([sys.executable, '-c', command, filename, str(deadline)]) as proc: + while time.time() < deadline: + try: + os.stat(filename) + except FileNotFoundError as e: + assert e.winerror == 2 # ERROR_FILE_NOT_FOUND + try: + proc.wait(1) + except subprocess.TimeoutExpired: + proc.terminate() + + @os_helper.skip_unless_symlink class NonLocalSymlinkTests(unittest.TestCase): diff --git a/Misc/ACKS b/Misc/ACKS index c6abfac531cbee..889bf8aeaea1ac 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1694,6 +1694,7 @@ Anthony Starks David Steele Oliver Steele Greg Stein +Itai Steinherz Marek Stepniowski Baruch Sterin Chris Stern diff --git a/Misc/NEWS.d/next/Windows/2022-03-13-20-35-41.bpo-46785.Pnknyl.rst b/Misc/NEWS.d/next/Windows/2022-03-13-20-35-41.bpo-46785.Pnknyl.rst new file mode 100644 index 00000000000000..0a87abd77c8ffe --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-03-13-20-35-41.bpo-46785.Pnknyl.rst @@ -0,0 +1 @@ +Fix race condition between :func:`os.stat` and unlinking a file on Windows, by using errors codes returned by ``FindFirstFileW()`` when appropriate in ``win32_xstat_impl``. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 03de4703239a7c..26c8e7bc2804d1 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1905,7 +1905,17 @@ win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result, /* Try reading the parent directory. */ if (!attributes_from_dir(path, &fileInfo, &tagInfo.ReparseTag)) { /* Cannot read the parent directory. */ - SetLastError(error); + switch (GetLastError()) { + case ERROR_FILE_NOT_FOUND: /* File cannot be found */ + case ERROR_PATH_NOT_FOUND: /* File parent directory cannot be found */ + case ERROR_NOT_READY: /* Drive exists but unavailable */ + case ERROR_BAD_NET_NAME: /* Remote drive unavailable */ + break; + /* Restore the error from CreateFileW(). */ + default: + SetLastError(error); + } + return -1; } if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { From d435ebd39ef2167517c02ca6c553864a9c783a0d Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 11 May 2022 00:06:42 -0700 Subject: [PATCH 174/237] gh-91966 Document where key functions are applied in the bisect module (GH-92602) (#92666) --- Doc/library/bisect.rst | 67 ++++++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 15 deletions(-) diff --git a/Doc/library/bisect.rst b/Doc/library/bisect.rst index edcd4aeb24aa7e..901a41f549202c 100644 --- a/Doc/library/bisect.rst +++ b/Doc/library/bisect.rst @@ -35,8 +35,11 @@ The following functions are provided: ``all(val >= x for val in a[i : hi])`` for the right side. *key* specifies a :term:`key function` of one argument that is used to - extract a comparison key from each input element. The default value is - ``None`` (compare the elements directly). + extract a comparison key from each element in the array. To support + searching complex records, the key function is not applied to the *x* value. + + If *key* is ``None``, the elements are compared directly with no + intervening function call. .. versionchanged:: 3.10 Added the *key* parameter. @@ -53,8 +56,11 @@ The following functions are provided: ``all(val > x for val in a[i : hi])`` for the right side. *key* specifies a :term:`key function` of one argument that is used to - extract a comparison key from each input element. The default value is - ``None`` (compare the elements directly). + extract a comparison key from each element in the array. To support + searching complex records, the key function is not applied to the *x* value. + + If *key* is ``None``, the elements are compared directly with no + intervening function call. .. versionchanged:: 3.10 Added the *key* parameter. @@ -64,14 +70,13 @@ The following functions are provided: Insert *x* in *a* in sorted order. - *key* specifies a :term:`key function` of one argument that is used to - extract a comparison key from each input element. The default value is - ``None`` (compare the elements directly). - This function first runs :func:`bisect_left` to locate an insertion point. Next, it runs the :meth:`insert` method on *a* to insert *x* at the appropriate position to maintain sort order. + To support inserting records in a table, the *key* function (if any) is + applied to *x* for the search step but not for the insertion step. + Keep in mind that the ``O(log n)`` search is dominated by the slow O(n) insertion step. @@ -85,14 +90,13 @@ The following functions are provided: Similar to :func:`insort_left`, but inserting *x* in *a* after any existing entries of *x*. - *key* specifies a :term:`key function` of one argument that is used to - extract a comparison key from each input element. The default value is - ``None`` (compare the elements directly). - This function first runs :func:`bisect_right` to locate an insertion point. Next, it runs the :meth:`insert` method on *a* to insert *x* at the appropriate position to maintain sort order. + To support inserting records in a table, the *key* function (if any) is + applied to *x* for the search step but not for the insertion step. + Keep in mind that the ``O(log n)`` search is dominated by the slow O(n) insertion step. @@ -194,8 +198,42 @@ a 'B', and so on:: >>> [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]] ['F', 'A', 'C', 'C', 'B', 'A', 'A'] -One technique to avoid repeated calls to a key function is to search a list of -precomputed keys to find the index of a record:: +The :func:`bisect`function and :func:`insort` functions also work with lists of +tuples. The *key* argument can serve to extract the field used for ordering +records in a table:: + + >>> from collections import namedtuple + >>> from operator import attrgetter + >>> from bisect import bisect, insort + >>> from pprint import pprint + + >>> Movie = namedtuple('Movie', ('name', 'released', 'director')) + + >>> movies = [ + ... Movie('Jaws', 1975, 'Speilberg'), + ... Movie('Titanic', 1997, 'Cameron'), + ... Movie('The Birds', 1963, 'Hitchcock'), + ... Movie('Aliens', 1986, 'Scott') + ... ] + + >>> # Find the first movie released on or after 1960 + >>> by_year = attrgetter('released') + >>> movies.sort(key=by_year) + >>> movies[bisect(movies, 1960, key=by_year)] + Movie(name='The Birds', released=1963, director='Hitchcock') + + >>> # Insert a movie while maintaining sort order + >>> romance = Movie('Love Story', 1970, 'Hiller') + >>> insort(movies, romance, key=by_year) + >>> pprint(movies) + [Movie(name='The Birds', released=1963, director='Hitchcock'), + Movie(name='Love Story', released=1970, director='Hiller'), + Movie(name='Jaws', released=1975, director='Speilberg'), + Movie(name='Aliens', released=1986, director='Scott'), + Movie(name='Titanic', released=1997, director='Cameron')] + +If the key function is expensive, it is possible to avoid repeated function +calls by searching a list of precomputed keys to find the index of a record:: >>> data = [('red', 5), ('blue', 1), ('yellow', 8), ('black', 0)] >>> data.sort(key=lambda r: r[1]) # Or use operator.itemgetter(1). @@ -208,4 +246,3 @@ precomputed keys to find the index of a record:: ('red', 5) >>> data[bisect_left(keys, 8)] ('yellow', 8) - From 7a84ea4ec16371fd2785b48cbe305da70a9dc7fc Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 11 May 2022 03:50:00 -0700 Subject: [PATCH 175/237] [3.10] Fix typo in unittest.rst: addCleanupModule -> addModuleCleanup (GH-92631) (GH-92660) (cherry picked from commit 38486ca212c0827d54e7b0d0b1e2c1ccc2bdad33) Co-authored-by: Mikhail Terekhov Automerge-Triggered-By: GH:serhiy-storchaka --- Doc/library/unittest.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index ae0c7d59964f16..67fec60263a4c6 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -2439,7 +2439,7 @@ To add cleanup code that must be run even in the case of an exception, use after :func:`setUpModule` if :func:`setUpModule` raises an exception. It is responsible for calling all the cleanup functions added by - :func:`addCleanupModule`. If you need cleanup functions to be called + :func:`addModuleCleanup`. If you need cleanup functions to be called *prior* to :func:`tearDownModule` then you can call :func:`doModuleCleanups` yourself. From 4730b0d6f3e6a6bc04de980c071a07adab41a1c9 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 11 May 2022 10:39:21 -0700 Subject: [PATCH 176/237] [3.10] gh-91810: ElementTree: Use text file's encoding by default in XML declaration (GH-91903) (GH-92664) ElementTree method write() and function tostring() now use the text file's encoding ("UTF-8" if not available) instead of locale encoding in XML declaration when encoding="unicode" is specified. (cherry picked from commit 707839b0fe02ba2c891a40f40e7a869d84c2c9c5) Co-authored-by: Serhiy Storchaka Automerge-Triggered-By: GH:serhiy-storchaka --- Lib/test/test_xml_etree.py | 31 +++++++++---------- Lib/xml/etree/ElementTree.py | 23 ++++++-------- ...2-04-25-10-23-01.gh-issue-91810.DOHa6B.rst | 5 +++ 3 files changed, 29 insertions(+), 30 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-04-25-10-23-01.gh-issue-91810.DOHa6B.rst diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index cb6d1697f1da88..9f5b5b73412f04 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -10,7 +10,6 @@ import html import io import itertools -import locale import operator import os import pickle @@ -978,15 +977,13 @@ def test_tostring_xml_declaration(self): def test_tostring_xml_declaration_unicode_encoding(self): elem = ET.XML('') - preferredencoding = locale.getpreferredencoding() self.assertEqual( - f"\n", - ET.tostring(elem, encoding='unicode', xml_declaration=True) + ET.tostring(elem, encoding='unicode', xml_declaration=True), + "\n" ) def test_tostring_xml_declaration_cases(self): elem = ET.XML('ø') - preferredencoding = locale.getpreferredencoding() TESTCASES = [ # (expected_retval, encoding, xml_declaration) # ... xml_declaration = None @@ -1013,7 +1010,7 @@ def test_tostring_xml_declaration_cases(self): b"ø", 'US-ASCII', True), (b"\n" b"\xf8", 'ISO-8859-1', True), - (f"\n" + ("\n" "ø", 'unicode', True), ] @@ -1051,11 +1048,10 @@ def test_tostringlist_xml_declaration(self): b"\n" ) - preferredencoding = locale.getpreferredencoding() stringlist = ET.tostringlist(elem, encoding='unicode', xml_declaration=True) self.assertEqual( ''.join(stringlist), - f"\n" + "\n" ) self.assertRegex(stringlist[0], r"^<\?xml version='1.0' encoding='.+'?>") self.assertEqual(['', '', ''], stringlist[1:]) @@ -3740,17 +3736,16 @@ def test_write_to_filename_as_unicode(self): encoding = f.encoding os_helper.unlink(TESTFN) - try: - '\xf8'.encode(encoding) - except UnicodeEncodeError: - self.skipTest(f'default file encoding {encoding} not supported') - tree = ET.ElementTree(ET.XML('''\xf8''')) tree.write(TESTFN, encoding='unicode') with open(TESTFN, 'rb') as f: data = f.read() expected = "\xf8".encode(encoding, 'xmlcharrefreplace') - self.assertEqual(data, expected) + if encoding.lower() in ('utf-8', 'ascii'): + self.assertEqual(data, expected) + else: + self.assertIn(b"ø''') + self.assertEqual(f.read(), convlinesep( + b'''\n''' + b'''ø''')) with open(TESTFN, 'w', encoding='ISO-8859-1') as f: tree.write(f, encoding='unicode') self.assertFalse(f.closed) with open(TESTFN, 'rb') as f: - self.assertEqual(f.read(), b'''\xf8''') + self.assertEqual(f.read(), convlinesep( + b'''\n''' + b'''\xf8''')) def test_write_to_binary_file(self): self.addCleanup(os_helper.unlink, TESTFN) diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py index 07be8609b83d6a..58da7c8d156239 100644 --- a/Lib/xml/etree/ElementTree.py +++ b/Lib/xml/etree/ElementTree.py @@ -728,16 +728,10 @@ def write(self, file_or_filename, encoding = "utf-8" else: encoding = "us-ascii" - enc_lower = encoding.lower() - with _get_writer(file_or_filename, enc_lower) as write: + with _get_writer(file_or_filename, encoding) as (write, declared_encoding): if method == "xml" and (xml_declaration or (xml_declaration is None and - enc_lower not in ("utf-8", "us-ascii", "unicode"))): - declared_encoding = encoding - if enc_lower == "unicode": - # Retrieve the default encoding for the xml declaration - import locale - declared_encoding = locale.getpreferredencoding() + declared_encoding.lower() not in ("utf-8", "us-ascii"))): write("\n" % ( declared_encoding,)) if method == "text": @@ -762,19 +756,20 @@ def _get_writer(file_or_filename, encoding): write = file_or_filename.write except AttributeError: # file_or_filename is a file name - if encoding == "unicode": - file = open(file_or_filename, "w") + if encoding.lower() == "unicode": + file = open(file_or_filename, "w", + errors="xmlcharrefreplace") else: file = open(file_or_filename, "w", encoding=encoding, errors="xmlcharrefreplace") with file: - yield file.write + yield file.write, file.encoding else: # file_or_filename is a file-like object # encoding determines if it is a text or binary writer - if encoding == "unicode": + if encoding.lower() == "unicode": # use a text writer as is - yield write + yield write, getattr(file_or_filename, "encoding", None) or "utf-8" else: # wrap a binary writer with TextIOWrapper with contextlib.ExitStack() as stack: @@ -805,7 +800,7 @@ def _get_writer(file_or_filename, encoding): # Keep the original file open when the TextIOWrapper is # destroyed stack.callback(file.detach) - yield file.write + yield file.write, encoding def _namespaces(elem, default_namespace=None): # identify namespaces used in this tree diff --git a/Misc/NEWS.d/next/Library/2022-04-25-10-23-01.gh-issue-91810.DOHa6B.rst b/Misc/NEWS.d/next/Library/2022-04-25-10-23-01.gh-issue-91810.DOHa6B.rst new file mode 100644 index 00000000000000..0711f8466b818f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-25-10-23-01.gh-issue-91810.DOHa6B.rst @@ -0,0 +1,5 @@ +:class:`~xml.etree.ElementTree.ElementTree` method +:meth:`~xml.etree.ElementTree.ElementTree.write` and function +:func:`~xml.etree.ElementTree.tostring` now use the text file's encoding +("UTF-8" if not available) instead of locale encoding in XML declaration +when ``encoding="unicode"`` is specified. From 9f29bdd8f07491d765a3730fcbf5826938b64dc4 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 11 May 2022 16:12:17 -0700 Subject: [PATCH 177/237] Fix minor documentation error in bisect docs (GH-92697) (cherry picked from commit b3f99b69d03cf0ea72a567a81e8bc4bc074ab303) Co-authored-by: Steve Dower --- Doc/library/bisect.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/bisect.rst b/Doc/library/bisect.rst index 901a41f549202c..513675d3685a52 100644 --- a/Doc/library/bisect.rst +++ b/Doc/library/bisect.rst @@ -198,7 +198,7 @@ a 'B', and so on:: >>> [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]] ['F', 'A', 'C', 'C', 'B', 'A', 'A'] -The :func:`bisect`function and :func:`insort` functions also work with lists of +The :func:`bisect` and :func:`insort` functions also work with lists of tuples. The *key* argument can serve to extract the field used for ordering records in a table:: From 9743524fc14db39e2f309cf3d372c7e8e18fc93a Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 11 May 2022 17:21:39 -0700 Subject: [PATCH 178/237] bpo-42627: Fix incorrect parsing of Windows registry proxy settings (GH-26307) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit b69297ea23c0ab9866ae8bd26a347a9b5df567a6) Co-authored-by: 狂男风 --- Lib/urllib/request.py | 36 ++++++++++--------- .../2021-05-22-07-58-59.bpo-42627.EejtD0.rst | 1 + 2 files changed, 21 insertions(+), 16 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2021-05-22-07-58-59.bpo-42627.EejtD0.rst diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 34b1b0b0b7643b..a0ef60b30de914 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -2674,22 +2674,26 @@ def getproxies_registry(): # Returned as Unicode but problems if not converted to ASCII proxyServer = str(winreg.QueryValueEx(internetSettings, 'ProxyServer')[0]) - if '=' in proxyServer: - # Per-protocol settings - for p in proxyServer.split(';'): - protocol, address = p.split('=', 1) - # See if address has a type:// prefix - if not re.match('(?:[^/:]+)://', address): - address = '%s://%s' % (protocol, address) - proxies[protocol] = address - else: - # Use one setting for all protocols - if proxyServer[:5] == 'http:': - proxies['http'] = proxyServer - else: - proxies['http'] = 'http://%s' % proxyServer - proxies['https'] = 'https://%s' % proxyServer - proxies['ftp'] = 'ftp://%s' % proxyServer + if '=' not in proxyServer and ';' not in proxyServer: + # Use one setting for all protocols. + proxyServer = 'http={0};https={0};ftp={0}'.format(proxyServer) + for p in proxyServer.split(';'): + protocol, address = p.split('=', 1) + # See if address has a type:// prefix + if not re.match('(?:[^/:]+)://', address): + # Add type:// prefix to address without specifying type + if protocol in ('http', 'https', 'ftp'): + # The default proxy type of Windows is HTTP + address = 'http://' + address + elif protocol == 'socks': + address = 'socks://' + address + proxies[protocol] = address + # Use SOCKS proxy for HTTP(S) protocols + if proxies.get('socks'): + # The default SOCKS proxy type of Windows is SOCKS4 + address = re.sub(r'^socks://', 'socks4://', proxies['socks']) + proxies['http'] = proxies.get('http') or address + proxies['https'] = proxies.get('https') or address internetSettings.Close() except (OSError, ValueError, TypeError): # Either registry key not found etc, or the value in an diff --git a/Misc/NEWS.d/next/Library/2021-05-22-07-58-59.bpo-42627.EejtD0.rst b/Misc/NEWS.d/next/Library/2021-05-22-07-58-59.bpo-42627.EejtD0.rst new file mode 100644 index 00000000000000..f165b9ced05d90 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-05-22-07-58-59.bpo-42627.EejtD0.rst @@ -0,0 +1 @@ +Fix incorrect parsing of Windows registry proxy settings From 5d62759f98e82625277f46ea86a1a29b07b8ffe1 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 12 May 2022 07:42:57 -0700 Subject: [PATCH 179/237] gh-92436: __future__ docs: add note on expectations for "from __future__ import annotations" (GH-92568) (cherry picked from commit 6582c96454ddb731eb412c2a473300172225fdb9) Co-authored-by: Jelle Zijlstra --- Doc/library/__future__.rst | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Doc/library/__future__.rst b/Doc/library/__future__.rst index 24bbd90d02cf76..8bd23daee73977 100644 --- a/Doc/library/__future__.rst +++ b/Doc/library/__future__.rst @@ -90,12 +90,20 @@ language using this mechanism: | generator_stop | 3.5.0b1 | 3.7 | :pep:`479`: | | | | | *StopIteration handling inside generators* | +------------------+-------------+--------------+---------------------------------------------+ -| annotations | 3.7.0b1 | 3.11 | :pep:`563`: | +| annotations | 3.7.0b1 | TBD [1]_ | :pep:`563`: | | | | | *Postponed evaluation of annotations* | +------------------+-------------+--------------+---------------------------------------------+ .. XXX Adding a new entry? Remember to update simple_stmts.rst, too. +.. [1] + ``from __future__ import annotations`` was previously scheduled to + become mandatory in Python 3.10, but the Python Steering Council + twice decided to delay the change + (`announcement for Python 3.10 `__; + `announcement for Python 3.11 `__). + No final decision has been made yet. See also :pep:`563` and :pep:`649`. + .. seealso:: From a24e67697362e76dd25d6901109277458b5971b9 Mon Sep 17 00:00:00 2001 From: Dennis Sweeney <36520290+sweeneyde@users.noreply.github.com> Date: Thu, 12 May 2022 11:31:43 -0400 Subject: [PATCH 180/237] [3.10] gh-92311: Let frame_setlineno jump over listcomps (GH-92717) --- Lib/test/test_sys_settrace.py | 48 +++++++++++++++++++ ...2-05-12-09-38-20.gh-issue-92311.VEgtts.rst | 1 + Objects/frameobject.c | 5 +- 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-05-12-09-38-20.gh-issue-92311.VEgtts.rst diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index 4f13bbd6bfda2f..76d1aeecf69e45 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -2094,6 +2094,54 @@ def gen(): yield 3 next(gen()) output.append(5) + + @jump_test(2, 3, [1, 3]) + def test_jump_forward_over_listcomp(output): + output.append(1) + x = [i for i in range(10)] + output.append(3) + + # checking for segfaults. + # See https://github.com/python/cpython/issues/92311 + @jump_test(3, 1, []) + def test_jump_backward_over_listcomp(output): + a = 1 + x = [i for i in range(10)] + c = 3 + + @jump_test(8, 2, [2, 7, 2]) + def test_jump_backward_over_listcomp_v2(output): + flag = False + output.append(2) + if flag: + return + x = [i for i in range(5)] + flag = 6 + output.append(7) + output.append(8) + + @async_jump_test(2, 3, [1, 3]) + async def test_jump_forward_over_async_listcomp(output): + output.append(1) + x = [i async for i in asynciter(range(10))] + output.append(3) + + @async_jump_test(3, 1, []) + async def test_jump_backward_over_async_listcomp(output): + a = 1 + x = [i async for i in asynciter(range(10))] + c = 3 + + @async_jump_test(8, 2, [2, 7, 2]) + async def test_jump_backward_over_async_listcomp_v2(output): + flag = False + output.append(2) + if flag: + return + x = [i async for i in asynciter(range(5))] + flag = 6 + output.append(7) + output.append(8) if __name__ == "__main__": diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-05-12-09-38-20.gh-issue-92311.VEgtts.rst b/Misc/NEWS.d/next/Core and Builtins/2022-05-12-09-38-20.gh-issue-92311.VEgtts.rst new file mode 100644 index 00000000000000..b800def656cbfd --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-05-12-09-38-20.gh-issue-92311.VEgtts.rst @@ -0,0 +1 @@ +Fixed a bug where setting ``frame.f_lineno`` to jump over a list comprehension could misbehave or crash. diff --git a/Objects/frameobject.c b/Objects/frameobject.c index d02cf9d3ba9f06..be84d33bf52389 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -195,7 +195,10 @@ markblocks(PyCodeObject *code_obj, int len) break; case GET_ITER: case GET_AITER: - block_stack = push_block(block_stack, Loop); + // For-loops get a Loop block, but comprehensions do not. + if (_Py_OPCODE(code[i + 1]) != CALL_FUNCTION) { + block_stack = push_block(block_stack, Loop); + } blocks[i+1] = block_stack; break; case FOR_ITER: From 48f2d8de24d636ee039a36a5b220ef76efc2edff Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 13 May 2022 06:32:39 -0700 Subject: [PATCH 181/237] Document Py_ssize_t. (GH-92512) It fixes 252 errors from a Sphinx nitpicky run (sphinx-build -n). But there's 8182 errors left. Co-authored-by: Ezio Melotti (cherry picked from commit 664aa94b570a4a8f3535efb2e3d638a4ab655943) Co-authored-by: Julien Palard --- Doc/c-api/arg.rst | 4 ++-- Doc/c-api/bytes.rst | 4 ++-- Doc/c-api/intro.rst | 7 +++++++ Doc/c-api/number.rst | 4 ++-- Doc/c-api/object.rst | 2 +- Doc/c-api/sys.rst | 4 ++-- Doc/c-api/typeobj.rst | 18 +++++++++--------- Doc/c-api/unicode.rst | 8 ++++---- Doc/howto/clinic.rst | 2 +- Doc/whatsnew/3.8.rst | 2 +- 10 files changed, 31 insertions(+), 24 deletions(-) diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst index 1d93b35dc1c884..926e5249347f84 100644 --- a/Doc/c-api/arg.rst +++ b/Doc/c-api/arg.rst @@ -286,7 +286,7 @@ Numbers Convert a Python integer to a C :c:type:`unsigned long long` without overflow checking. -``n`` (:class:`int`) [Py_ssize_t] +``n`` (:class:`int`) [:c:type:`Py_ssize_t`] Convert a Python integer to a C :c:type:`Py_ssize_t`. ``c`` (:class:`bytes` or :class:`bytearray` of length 1) [char] @@ -613,7 +613,7 @@ Building values ``K`` (:class:`int`) [unsigned long long] Convert a C :c:type:`unsigned long long` to a Python integer object. - ``n`` (:class:`int`) [Py_ssize_t] + ``n`` (:class:`int`) [:c:type:`Py_ssize_t`] Convert a C :c:type:`Py_ssize_t` to a Python integer. ``c`` (:class:`bytes` of length 1) [char] diff --git a/Doc/c-api/bytes.rst b/Doc/c-api/bytes.rst index 32c7b80dc7ac63..ffbfb5a61b44bb 100644 --- a/Doc/c-api/bytes.rst +++ b/Doc/c-api/bytes.rst @@ -84,8 +84,8 @@ called with a non-bytes parameter. | :attr:`%lu` | unsigned long | Equivalent to | | | | ``printf("%lu")``. [1]_ | +-------------------+---------------+--------------------------------+ - | :attr:`%zd` | Py_ssize_t | Equivalent to | - | | | ``printf("%zd")``. [1]_ | + | :attr:`%zd` | :c:type:`\ | Equivalent to | + | | Py_ssize_t` | ``printf("%zd")``. [1]_ | +-------------------+---------------+--------------------------------+ | :attr:`%zu` | size_t | Equivalent to | | | | ``printf("%zu")``. [1]_ | diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst index 2d85d30702df9c..083f6d32c79f83 100644 --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -502,6 +502,13 @@ data attributes of a new object type, and another is used to describe the value of a complex number. These will be discussed together with the functions that use them. +.. c:type:: Py_ssize_t + + A signed integral type such that ``sizeof(Py_ssize_t) == sizeof(size_t)``. + C99 doesn't define such a thing directly (size_t is an unsigned integral type). + See :pep:`353` for details. ``PY_SSIZE_T_MAX`` is the largest positive value + of type :c:type:`Py_ssize_t`. + .. _api-exceptions: diff --git a/Doc/c-api/number.rst b/Doc/c-api/number.rst index 11c9c67d36a678..70b91f8c2d0ca1 100644 --- a/Doc/c-api/number.rst +++ b/Doc/c-api/number.rst @@ -273,11 +273,11 @@ Number Protocol .. c:function:: Py_ssize_t PyNumber_AsSsize_t(PyObject *o, PyObject *exc) - Returns *o* converted to a Py_ssize_t value if *o* can be interpreted as an + Returns *o* converted to a :c:type:`Py_ssize_t` value if *o* can be interpreted as an integer. If the call fails, an exception is raised and ``-1`` is returned. If *o* can be converted to a Python int but the attempt to - convert to a Py_ssize_t value would raise an :exc:`OverflowError`, then the + convert to a :c:type:`Py_ssize_t` value would raise an :exc:`OverflowError`, then the *exc* argument is the type of exception that will be raised (usually :exc:`IndexError` or :exc:`OverflowError`). If *exc* is ``NULL``, then the exception is cleared and the value is clipped to ``PY_SSIZE_T_MIN`` for a negative diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index 9dcfd769c64a05..07a625bac02fc4 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -258,7 +258,7 @@ Object Protocol .. versionchanged:: 3.2 The return type is now Py_hash_t. This is a signed integer the same size - as Py_ssize_t. + as :c:type:`Py_ssize_t`. .. c:function:: Py_hash_t PyObject_HashNotImplemented(PyObject *o) diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst index 350d4e1de41ba7..7cf0a6b51f7ddc 100644 --- a/Doc/c-api/sys.rst +++ b/Doc/c-api/sys.rst @@ -323,7 +323,7 @@ accessible to C code. They all work with the current interpreter thread's leaks.) Note that ``#`` format characters should always be treated as - ``Py_ssize_t``, regardless of whether ``PY_SSIZE_T_CLEAN`` was defined. + :c:type:`Py_ssize_t`, regardless of whether ``PY_SSIZE_T_CLEAN`` was defined. :func:`sys.audit` performs the same function from Python code. @@ -331,7 +331,7 @@ accessible to C code. They all work with the current interpreter thread's .. versionchanged:: 3.8.2 - Require ``Py_ssize_t`` for ``#`` format characters. Previously, an + Require :c:type:`Py_ssize_t` for ``#`` format characters. Previously, an unavoidable deprecation warning was raised. diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index d24eabe7e8d554..327a8c1208458e 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -43,13 +43,13 @@ Quick Reference +================================================+===================================+===================+===+===+===+===+ | :c:member:`~PyTypeObject.tp_name` | const char * | __name__ | X | X | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_basicsize` | Py_ssize_t | | X | X | | X | + | :c:member:`~PyTypeObject.tp_basicsize` | :c:type:`Py_ssize_t` | | X | X | | X | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_itemsize` | Py_ssize_t | | | X | | X | + | :c:member:`~PyTypeObject.tp_itemsize` | :c:type:`Py_ssize_t` | | | X | | X | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | :c:member:`~PyTypeObject.tp_dealloc` | :c:type:`destructor` | | X | X | | X | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_vectorcall_offset` | Py_ssize_t | | | X | | X | + | :c:member:`~PyTypeObject.tp_vectorcall_offset` | :c:type:`Py_ssize_t` | | | X | | X | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | (:c:member:`~PyTypeObject.tp_getattr`) | :c:type:`getattrfunc` | __getattribute__, | | | | G | | | | __getattr__ | | | | | @@ -96,7 +96,7 @@ Quick Reference | | | __gt__, | | | | | | | | __ge__ | | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_weaklistoffset` | Py_ssize_t | | | X | | ? | + | :c:member:`~PyTypeObject.tp_weaklistoffset` | :c:type:`Py_ssize_t` | | | X | | ? | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | :c:member:`~PyTypeObject.tp_iter` | :c:type:`getiterfunc` | __iter__ | | | | X | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ @@ -117,7 +117,7 @@ Quick Reference | :c:member:`~PyTypeObject.tp_descr_set` | :c:type:`descrsetfunc` | __set__, | | | | X | | | | __delete__ | | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_dictoffset` | Py_ssize_t | | | X | | ? | + | :c:member:`~PyTypeObject.tp_dictoffset` | :c:type:`Py_ssize_t` | | | X | | ? | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | :c:member:`~PyTypeObject.tp_init` | :c:type:`initproc` | __init__ | X | X | | X | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ @@ -333,7 +333,7 @@ slot typedefs | :c:type:`allocfunc` | .. line-block:: | :c:type:`PyObject` * | | | | | | | :c:type:`PyTypeObject` * | | -| | Py_ssize_t | | +| | :c:type:`Py_ssize_t` | | +-----------------------------+-----------------------------+----------------------+ | :c:type:`destructor` | void * | void | +-----------------------------+-----------------------------+----------------------+ @@ -405,7 +405,7 @@ slot typedefs +-----------------------------+-----------------------------+----------------------+ | :c:type:`iternextfunc` | :c:type:`PyObject` * | :c:type:`PyObject` * | +-----------------------------+-----------------------------+----------------------+ -| :c:type:`lenfunc` | :c:type:`PyObject` * | Py_ssize_t | +| :c:type:`lenfunc` | :c:type:`PyObject` * | :c:type:`Py_ssize_t` | +-----------------------------+-----------------------------+----------------------+ | :c:type:`getbufferproc` | .. line-block:: | int | | | | | @@ -438,12 +438,12 @@ slot typedefs | :c:type:`ssizeargfunc` | .. line-block:: | :c:type:`PyObject` * | | | | | | | :c:type:`PyObject` * | | -| | Py_ssize_t | | +| | :c:type:`Py_ssize_t` | | +-----------------------------+-----------------------------+----------------------+ | :c:type:`ssizeobjargproc` | .. line-block:: | int | | | | | | | :c:type:`PyObject` * | | -| | Py_ssize_t | | +| | :c:type:`Py_ssize_t` | | +-----------------------------+-----------------------------+----------------------+ | :c:type:`objobjproc` | .. line-block:: | int | | | | | diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index cf7d2232125c89..09ded4c32db07e 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -490,11 +490,11 @@ APIs: | :attr:`%llu` | unsigned long long | Equivalent to | | | | ``printf("%llu")``. [1]_ | +-------------------+---------------------+----------------------------------+ - | :attr:`%zd` | Py_ssize_t | Equivalent to | - | | | ``printf("%zd")``. [1]_ | + | :attr:`%zd` | :c:type:`\ | Equivalent to | + | | Py_ssize_t` | ``printf("%zd")``. [1]_ | +-------------------+---------------------+----------------------------------+ - | :attr:`%zi` | Py_ssize_t | Equivalent to | - | | | ``printf("%zi")``. [1]_ | + | :attr:`%zi` | :c:type:`\ | Equivalent to | + | | Py_ssize_t` | ``printf("%zi")``. [1]_ | +-------------------+---------------------+----------------------------------+ | :attr:`%zu` | size_t | Equivalent to | | | | ``printf("%zu")``. [1]_ | diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 3a3653a5ee3a3e..f2195405fe96fe 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1350,7 +1350,7 @@ Here's the simplest example of a custom converter, from ``Modules/zlibmodule.c`` /*[python end generated code: output=da39a3ee5e6b4b0d input=35521e4e733823c7]*/ This block adds a converter to Argument Clinic named ``ssize_t``. Parameters -declared as ``ssize_t`` will be declared as type ``Py_ssize_t``, and will +declared as ``ssize_t`` will be declared as type :c:type:`Py_ssize_t`, and will be parsed by the ``'O&'`` format unit, which will call the ``ssize_t_converter`` converter function. ``ssize_t`` variables automatically support default values. diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 7c293a501895b3..94d3b3f15fd29e 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -1490,7 +1490,7 @@ Optimizations first introduced in Python 3.4. It offers better performance and smaller size compared to Protocol 3 available since Python 3.0. -* Removed one ``Py_ssize_t`` member from ``PyGC_Head``. All GC tracked +* Removed one :c:type:`Py_ssize_t` member from ``PyGC_Head``. All GC tracked objects (e.g. tuple, list, dict) size is reduced 4 or 8 bytes. (Contributed by Inada Naoki in :issue:`33597`.) From 597ff241889f975a3ccc286ddb1258208dc57aea Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 13 May 2022 13:11:05 -0700 Subject: [PATCH 182/237] gh-92611: Link to PEP 594 sections & add key detail in doc deprecation notices (GH-92612) (cherry picked from commit 9f68dab3d327335b938046c50b4f09944e993cc8) Co-authored-by: CAM Gerlach --- Doc/library/aifc.rst | 3 ++- Doc/library/asynchat.rst | 3 ++- Doc/library/asyncore.rst | 3 ++- Doc/library/audioop.rst | 3 ++- Doc/library/cgi.rst | 3 ++- Doc/library/cgitb.rst | 3 ++- Doc/library/chunk.rst | 3 ++- Doc/library/crypt.rst | 4 +++- Doc/library/imghdr.rst | 3 ++- Doc/library/mailcap.rst | 5 +++-- Doc/library/msilib.rst | 3 ++- Doc/library/nis.rst | 3 ++- Doc/library/ossaudiodev.rst | 3 ++- Doc/library/pipes.rst | 4 +++- Doc/library/smtpd.rst | 3 ++- Doc/library/sndhdr.rst | 3 ++- Doc/library/spwd.rst | 3 ++- Doc/library/sunau.rst | 3 ++- Doc/library/telnetlib.rst | 3 ++- Doc/library/uu.rst | 4 +++- Doc/library/xdrlib.rst | 3 ++- 21 files changed, 46 insertions(+), 22 deletions(-) diff --git a/Doc/library/aifc.rst b/Doc/library/aifc.rst index edb4bf86e5a0aa..fa277857574a3a 100644 --- a/Doc/library/aifc.rst +++ b/Doc/library/aifc.rst @@ -14,7 +14,8 @@ .. deprecated:: 3.11 - The :mod:`aifc` module is deprecated (see :pep:`594` for details). + The :mod:`aifc` module is deprecated + (see :pep:`PEP 594 <594#aifc>` for details). -------------- diff --git a/Doc/library/asynchat.rst b/Doc/library/asynchat.rst index 4354444a1d3314..7cc9d99779bbbb 100644 --- a/Doc/library/asynchat.rst +++ b/Doc/library/asynchat.rst @@ -11,7 +11,8 @@ **Source code:** :source:`Lib/asynchat.py` .. deprecated:: 3.6 - :mod:`asynchat` will be removed in Python 3.12 (:pep:`594`). + :mod:`asynchat` will be removed in Python 3.12 + (see :pep:`PEP 594 <594#asynchat>` for details). Please use :mod:`asyncio` instead. -------------- diff --git a/Doc/library/asyncore.rst b/Doc/library/asyncore.rst index e481e13db76f70..a732fd7ba4f152 100644 --- a/Doc/library/asyncore.rst +++ b/Doc/library/asyncore.rst @@ -14,7 +14,8 @@ **Source code:** :source:`Lib/asyncore.py` .. deprecated:: 3.6 - :mod:`asyncore` will be removed in Python 3.12 (:pep:`594`). + :mod:`asyncore` will be removed in Python 3.12 + (see :pep:`PEP 594 <594#asyncore>` for details). Please use :mod:`asyncio` instead. -------------- diff --git a/Doc/library/audioop.rst b/Doc/library/audioop.rst index eae206084f0900..649c99e796282c 100644 --- a/Doc/library/audioop.rst +++ b/Doc/library/audioop.rst @@ -6,7 +6,8 @@ :deprecated: .. deprecated:: 3.11 - The :mod:`audioop` module is deprecated (see :pep:`594` for details). + The :mod:`audioop` module is deprecated + (see :pep:`PEP 594 <594#audioop>` for details). -------------- diff --git a/Doc/library/cgi.rst b/Doc/library/cgi.rst index 306aa8d19ad726..eeb80ed57ef35d 100644 --- a/Doc/library/cgi.rst +++ b/Doc/library/cgi.rst @@ -16,7 +16,8 @@ single: Common Gateway Interface .. deprecated:: 3.11 - The :mod:`cgi` module is deprecated (see :pep:`594` for details). + The :mod:`cgi` module is deprecated + (see :pep:`PEP 594 <594#cgi>` for details and alternatives). -------------- diff --git a/Doc/library/cgitb.rst b/Doc/library/cgitb.rst index 349414610bd40a..3b0b106abacd50 100644 --- a/Doc/library/cgitb.rst +++ b/Doc/library/cgitb.rst @@ -17,7 +17,8 @@ single: tracebacks; in CGI scripts .. deprecated:: 3.11 - The :mod:`cgitb` module is deprecated (see :pep:`594` for details). + The :mod:`cgitb` module is deprecated + (see :pep:`PEP 594 <594#cgitb>` for details). -------------- diff --git a/Doc/library/chunk.rst b/Doc/library/chunk.rst index 7999420f536d76..5a84c8904f7145 100644 --- a/Doc/library/chunk.rst +++ b/Doc/library/chunk.rst @@ -18,7 +18,8 @@ single: RMFF .. deprecated:: 3.11 - The :mod:`chunk` module is deprecated (see :pep:`594` for details). + The :mod:`chunk` module is deprecated + (see :pep:`PEP 594 <594#chunk>` for details). -------------- diff --git a/Doc/library/crypt.rst b/Doc/library/crypt.rst index 3189ece048a26e..e795f10f50eec3 100644 --- a/Doc/library/crypt.rst +++ b/Doc/library/crypt.rst @@ -17,7 +17,9 @@ pair: cipher; DES .. deprecated:: 3.11 - The :mod:`crypt` module is deprecated (see :pep:`594` for details). + The :mod:`crypt` module is deprecated + (see :pep:`PEP 594 <594#crypt>` for details and alternatives). + The :mod:`hashlib` module is a potential replacement for certain use cases. -------------- diff --git a/Doc/library/imghdr.rst b/Doc/library/imghdr.rst index 084fef73daf28d..c17bf897b9be91 100644 --- a/Doc/library/imghdr.rst +++ b/Doc/library/imghdr.rst @@ -8,7 +8,8 @@ **Source code:** :source:`Lib/imghdr.py` .. deprecated:: 3.11 - The :mod:`imghdr` module is deprecated (see :pep:`594` for details). + The :mod:`imghdr` module is deprecated + (see :pep:`PEP 594 <594#imghdr>` for details and alternatives). -------------- diff --git a/Doc/library/mailcap.rst b/Doc/library/mailcap.rst index 416b181f45a772..e2e5bb34456373 100644 --- a/Doc/library/mailcap.rst +++ b/Doc/library/mailcap.rst @@ -8,8 +8,9 @@ **Source code:** :source:`Lib/mailcap.py` .. deprecated:: 3.11 - The :mod:`mailcap` module is deprecated. See :pep:`594` for the rationale - and the :mod:`mimetypes` module for an alternative. + The :mod:`mailcap` module is deprecated + (see :pep:`PEP 594 <594#mailcap>` for details). + The :mod:`mimetypes` module provides an alternative. -------------- diff --git a/Doc/library/msilib.rst b/Doc/library/msilib.rst index 5ce18a1f75fc21..0eba2275c8e051 100644 --- a/Doc/library/msilib.rst +++ b/Doc/library/msilib.rst @@ -14,7 +14,8 @@ .. index:: single: msi .. deprecated:: 3.11 - The :mod:`msilib` module is deprecated (see :pep:`594` for details). + The :mod:`msilib` module is deprecated + (see :pep:`PEP 594 <594#msilib>` for details). -------------- diff --git a/Doc/library/nis.rst b/Doc/library/nis.rst index f6b6ea83946b0e..49fe62954cce8a 100644 --- a/Doc/library/nis.rst +++ b/Doc/library/nis.rst @@ -11,7 +11,8 @@ .. sectionauthor:: Moshe Zadka .. deprecated:: 3.11 - The :mod:`nis` module is deprecated (see :pep:`594` for details). + The :mod:`nis` module is deprecated + (see :pep:`PEP 594 <594#nis>` for details). -------------- diff --git a/Doc/library/ossaudiodev.rst b/Doc/library/ossaudiodev.rst index e0f0a6b8259e4f..728ee3036057dd 100644 --- a/Doc/library/ossaudiodev.rst +++ b/Doc/library/ossaudiodev.rst @@ -7,7 +7,8 @@ :deprecated: .. deprecated:: 3.11 - The :mod:`ossaudiodev` module is deprecated (see :pep:`594` for details). + The :mod:`ossaudiodev` module is deprecated + (see :pep:`PEP 594 <594#ossaudiodev>` for details). -------------- diff --git a/Doc/library/pipes.rst b/Doc/library/pipes.rst index 4de8c51bcae049..1c5bb8bddaafbc 100644 --- a/Doc/library/pipes.rst +++ b/Doc/library/pipes.rst @@ -11,7 +11,9 @@ **Source code:** :source:`Lib/pipes.py` .. deprecated:: 3.11 - The :mod:`pipes` module is deprecated (see :pep:`594` for details). + The :mod:`pipes` module is deprecated + (see :pep:`PEP 594 <594#pipes>` for details). + Please use the :mod:`subprocess` module instead. -------------- diff --git a/Doc/library/smtpd.rst b/Doc/library/smtpd.rst index a39bc024047fd3..8fd009e5b23659 100644 --- a/Doc/library/smtpd.rst +++ b/Doc/library/smtpd.rst @@ -15,7 +15,8 @@ This module offers several classes to implement SMTP (email) servers. .. deprecated:: 3.6 - :mod:`smtpd` will be removed in Python 3.12 (:pep:`594`). + :mod:`smtpd` will be removed in Python 3.12 + (see :pep:`PEP 594 <594#smtpd>` for details). The `aiosmtpd `_ package is a recommended replacement for this module. It is based on :mod:`asyncio` and provides a more straightforward API. diff --git a/Doc/library/sndhdr.rst b/Doc/library/sndhdr.rst index 41bce18b9cd849..3ca36f270dade1 100644 --- a/Doc/library/sndhdr.rst +++ b/Doc/library/sndhdr.rst @@ -15,7 +15,8 @@ single: u-LAW .. deprecated:: 3.11 - The :mod:`sndhdr` module is deprecated (see :pep:`594` for details). + The :mod:`sndhdr` module is deprecated + (see :pep:`PEP 594 <594#sndhdr>` for details and alternatives). -------------- diff --git a/Doc/library/spwd.rst b/Doc/library/spwd.rst index cb31a10a52e001..40f50de07babff 100644 --- a/Doc/library/spwd.rst +++ b/Doc/library/spwd.rst @@ -7,7 +7,8 @@ :deprecated: .. deprecated:: 3.11 - The :mod:`spwd` module is deprecated (see :pep:`594` for details). + The :mod:`spwd` module is deprecated + (see :pep:`PEP 594 <594#spwd>` for details and alternatives). -------------- diff --git a/Doc/library/sunau.rst b/Doc/library/sunau.rst index cfb1257f585484..b4d996e67e17cf 100644 --- a/Doc/library/sunau.rst +++ b/Doc/library/sunau.rst @@ -10,7 +10,8 @@ **Source code:** :source:`Lib/sunau.py` .. deprecated:: 3.11 - The :mod:`sunau` module is deprecated (see :pep:`594` for details). + The :mod:`sunau` module is deprecated + (see :pep:`PEP 594 <594#sunau>` for details). -------------- diff --git a/Doc/library/telnetlib.rst b/Doc/library/telnetlib.rst index 97b0a713e44223..48a927c8ac96b2 100644 --- a/Doc/library/telnetlib.rst +++ b/Doc/library/telnetlib.rst @@ -12,7 +12,8 @@ .. index:: single: protocol; Telnet .. deprecated:: 3.11 - The :mod:`telnetlib` module is deprecated (see :pep:`594` for details). + The :mod:`telnetlib` module is deprecated + (see :pep:`PEP 594 <594#telnetlib>` for details and alternatives). -------------- diff --git a/Doc/library/uu.rst b/Doc/library/uu.rst index c341bc83dcfed0..026ec415c9da65 100644 --- a/Doc/library/uu.rst +++ b/Doc/library/uu.rst @@ -10,7 +10,9 @@ **Source code:** :source:`Lib/uu.py` .. deprecated:: 3.11 - The :mod:`uu` module is deprecated (see :pep:`594` for details). + The :mod:`uu` module is deprecated + (see :pep:`PEP 594 <594#uu-and-the-uu-encoding>` for details). + :mod:`base64` is a modern alternative. -------------- diff --git a/Doc/library/xdrlib.rst b/Doc/library/xdrlib.rst index 060b2e2c60df6d..a3124a986524bd 100644 --- a/Doc/library/xdrlib.rst +++ b/Doc/library/xdrlib.rst @@ -12,7 +12,8 @@ single: External Data Representation .. deprecated:: 3.11 - The :mod:`xdrlib` module is deprecated (see :pep:`594` for details). + The :mod:`xdrlib` module is deprecated + (see :pep:`PEP 594 <594#xdrlib>` for details). -------------- From 56e9fb3e3b1c51c9c32dda9d51f0379f711bc7d7 Mon Sep 17 00:00:00 2001 From: thueringa Date: Fri, 13 May 2022 23:09:06 +0200 Subject: [PATCH 183/237] Fix typo in argparse docs. (GH-92691) (#92729) --- Doc/library/argparse.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index d853d2afbe372f..e8e54d6c58df36 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -502,7 +502,7 @@ disallowed. fromfile_prefix_chars ^^^^^^^^^^^^^^^^^^^^^ -Sometimes, for example when dealing with a particularly long argument lists, it +Sometimes, for example when dealing with a particularly long argument list, it may make sense to keep the list of arguments in a file rather than typing it out at the command line. If the ``fromfile_prefix_chars=`` argument is given to the :class:`ArgumentParser` constructor, then arguments that start with any of the From 36d42e701f8a4040e7daf70138217038bfde3c78 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 14 May 2022 08:01:53 -0700 Subject: [PATCH 184/237] Check result of utc_to_seconds and skip fold probe in pure Python (GH-91582) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `utc_to_seconds` call can fail, here's a minimal reproducer on Linux: TZ=UTC python -c "from datetime import *; datetime.fromtimestamp(253402300799 + 1)" The old behavior still raised an error in a similar way, but only because subsequent calculations happened to fail as well. Better to fail fast. This also refactors the tests to split out the `fromtimestamp` and `utcfromtimestamp` tests, and to get us closer to the actual desired limits of the functions. As part of this, we also changed the way we detect platforms where the same limits don't necessarily apply (e.g. Windows). As part of refactoring the tests to hit this condition explicitly (even though the user-facing behvior doesn't change in any way we plan to guarantee), I noticed that there was a difference in the places that `datetime.utcfromtimestamp` fails in the C and pure Python versions, which was fixed by skipping the "probe for fold" logic for UTC specifically — since UTC doesn't have any folds or gaps, we were never going to find a fold value anyway. This should prevent some failures in the pure python `utcfromtimestamp` method on timestamps close to 0001-01-01. There are two separate news entries for this because one is a potentially user-facing change, the other is an internal code correctness change that, if anything, changes some error messages. The two happen to be coupled because of the test refactoring, but they are probably best thought of as independent changes. Fixes GH-91581 (cherry picked from commit 83c0247d47b99f4571e35ea95361436e1d2a61cd) Co-authored-by: Paul Ganssle <1377457+pganssle@users.noreply.github.com> --- Lib/datetime.py | 4 +- Lib/test/datetimetester.py | 128 +++++++++++++----- ...2-04-15-13-16-25.gh-issue-91581.9OGsrN.rst | 6 + ...2-05-11-14-34-09.gh-issue-91581.glkou2.rst | 5 + Modules/_datetimemodule.c | 4 + 5 files changed, 109 insertions(+), 38 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-04-15-13-16-25.gh-issue-91581.9OGsrN.rst create mode 100644 Misc/NEWS.d/next/Library/2022-05-11-14-34-09.gh-issue-91581.glkou2.rst diff --git a/Lib/datetime.py b/Lib/datetime.py index 6bf37ccfab7ac8..d087c9852c7d2a 100644 --- a/Lib/datetime.py +++ b/Lib/datetime.py @@ -1652,7 +1652,7 @@ def _fromtimestamp(cls, t, utc, tz): y, m, d, hh, mm, ss, weekday, jday, dst = converter(t) ss = min(ss, 59) # clamp out leap seconds if the platform has them result = cls(y, m, d, hh, mm, ss, us, tz) - if tz is None: + if tz is None and not utc: # As of version 2015f max fold in IANA database is # 23 hours at 1969-09-30 13:00:00 in Kwajalein. # Let's probe 24 hours in the past to detect a transition: @@ -1673,7 +1673,7 @@ def _fromtimestamp(cls, t, utc, tz): probe2 = cls(y, m, d, hh, mm, ss, us, tz) if probe2 == result: result._fold = 1 - else: + elif tz is not None: result = tz.fromutc(result) return result diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 58336595c1f574..43eab642b8f7d4 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -2467,45 +2467,101 @@ def test_microsecond_rounding(self): self.assertEqual(t.microsecond, 7812) def test_timestamp_limits(self): - # minimum timestamp - min_dt = self.theclass.min.replace(tzinfo=timezone.utc) + with self.subTest("minimum UTC"): + min_dt = self.theclass.min.replace(tzinfo=timezone.utc) + min_ts = min_dt.timestamp() + + # This test assumes that datetime.min == 0000-01-01T00:00:00.00 + # If that assumption changes, this value can change as well + self.assertEqual(min_ts, -62135596800) + + with self.subTest("maximum UTC"): + # Zero out microseconds to avoid rounding issues + max_dt = self.theclass.max.replace(tzinfo=timezone.utc, + microsecond=0) + max_ts = max_dt.timestamp() + + # This test assumes that datetime.max == 9999-12-31T23:59:59.999999 + # If that assumption changes, this value can change as well + self.assertEqual(max_ts, 253402300799.0) + + def test_fromtimestamp_limits(self): + try: + self.theclass.fromtimestamp(-2**32 - 1) + except (OSError, OverflowError): + self.skipTest("Test not valid on this platform") + + # XXX: Replace these with datetime.{min,max}.timestamp() when we solve + # the issue with gh-91012 + min_dt = self.theclass.min + timedelta(days=1) min_ts = min_dt.timestamp() + + max_dt = self.theclass.max.replace(microsecond=0) + max_ts = ((self.theclass.max - timedelta(hours=23)).timestamp() + + timedelta(hours=22, minutes=59, seconds=59).total_seconds()) + + for (test_name, ts, expected) in [ + ("minimum", min_ts, min_dt), + ("maximum", max_ts, max_dt), + ]: + with self.subTest(test_name, ts=ts, expected=expected): + actual = self.theclass.fromtimestamp(ts) + + self.assertEqual(actual, expected) + + # Test error conditions + test_cases = [ + ("Too small by a little", min_ts - timedelta(days=1, hours=12).total_seconds()), + ("Too small by a lot", min_ts - timedelta(days=400).total_seconds()), + ("Too big by a little", max_ts + timedelta(days=1).total_seconds()), + ("Too big by a lot", max_ts + timedelta(days=400).total_seconds()), + ] + + for test_name, ts in test_cases: + with self.subTest(test_name, ts=ts): + with self.assertRaises((ValueError, OverflowError)): + # converting a Python int to C time_t can raise a + # OverflowError, especially on 32-bit platforms. + self.theclass.fromtimestamp(ts) + + def test_utcfromtimestamp_limits(self): try: - # date 0001-01-01 00:00:00+00:00: timestamp=-62135596800 - self.assertEqual(self.theclass.fromtimestamp(min_ts, tz=timezone.utc), - min_dt) - except (OverflowError, OSError) as exc: - # the date 0001-01-01 doesn't fit into 32-bit time_t, - # or platform doesn't support such very old date - self.skipTest(str(exc)) - - # maximum timestamp: set seconds to zero to avoid rounding issues - max_dt = self.theclass.max.replace(tzinfo=timezone.utc, - second=0, microsecond=0) + self.theclass.utcfromtimestamp(-2**32 - 1) + except (OSError, OverflowError): + self.skipTest("Test not valid on this platform") + + min_dt = self.theclass.min.replace(tzinfo=timezone.utc) + min_ts = min_dt.timestamp() + + max_dt = self.theclass.max.replace(microsecond=0, tzinfo=timezone.utc) max_ts = max_dt.timestamp() - # date 9999-12-31 23:59:00+00:00: timestamp 253402300740 - self.assertEqual(self.theclass.fromtimestamp(max_ts, tz=timezone.utc), - max_dt) - - # number of seconds greater than 1 year: make sure that the new date - # is not valid in datetime.datetime limits - delta = 3600 * 24 * 400 - - # too small - ts = min_ts - delta - # converting a Python int to C time_t can raise a OverflowError, - # especially on 32-bit platforms. - with self.assertRaises((ValueError, OverflowError)): - self.theclass.fromtimestamp(ts) - with self.assertRaises((ValueError, OverflowError)): - self.theclass.utcfromtimestamp(ts) - - # too big - ts = max_dt.timestamp() + delta - with self.assertRaises((ValueError, OverflowError)): - self.theclass.fromtimestamp(ts) - with self.assertRaises((ValueError, OverflowError)): - self.theclass.utcfromtimestamp(ts) + + for (test_name, ts, expected) in [ + ("minimum", min_ts, min_dt.replace(tzinfo=None)), + ("maximum", max_ts, max_dt.replace(tzinfo=None)), + ]: + with self.subTest(test_name, ts=ts, expected=expected): + try: + actual = self.theclass.utcfromtimestamp(ts) + except (OSError, OverflowError) as exc: + self.skipTest(str(exc)) + + self.assertEqual(actual, expected) + + # Test error conditions + test_cases = [ + ("Too small by a little", min_ts - 1), + ("Too small by a lot", min_ts - timedelta(days=400).total_seconds()), + ("Too big by a little", max_ts + 1), + ("Too big by a lot", max_ts + timedelta(days=400).total_seconds()), + ] + + for test_name, ts in test_cases: + with self.subTest(test_name, ts=ts): + with self.assertRaises((ValueError, OverflowError)): + # converting a Python int to C time_t can raise a + # OverflowError, especially on 32-bit platforms. + self.theclass.utcfromtimestamp(ts) def test_insane_fromtimestamp(self): # It's possible that some platform maps time_t to double, diff --git a/Misc/NEWS.d/next/Library/2022-04-15-13-16-25.gh-issue-91581.9OGsrN.rst b/Misc/NEWS.d/next/Library/2022-04-15-13-16-25.gh-issue-91581.9OGsrN.rst new file mode 100644 index 00000000000000..1c3008f4255783 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-15-13-16-25.gh-issue-91581.9OGsrN.rst @@ -0,0 +1,6 @@ +Remove an unhandled error case in the C implementation of calls to +:meth:`datetime.fromtimestamp ` with no time +zone (i.e. getting a local time from an epoch timestamp). This should have no +user-facing effect other than giving a possibly more accurate error message +when called with timestamps that fall on 10000-01-01 in the local time. Patch +by Paul Ganssle. diff --git a/Misc/NEWS.d/next/Library/2022-05-11-14-34-09.gh-issue-91581.glkou2.rst b/Misc/NEWS.d/next/Library/2022-05-11-14-34-09.gh-issue-91581.glkou2.rst new file mode 100644 index 00000000000000..846f57844a6751 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-05-11-14-34-09.gh-issue-91581.glkou2.rst @@ -0,0 +1,5 @@ +:meth:`~datetime.datetime.utcfromtimestamp` no longer attempts to resolve +``fold`` in the pure Python implementation, since the fold is never 1 in UTC. +In addition to being slightly faster in the common case, this also prevents +some errors when the timestamp is close to :attr:`datetime.min +`. Patch by Paul Ganssle. diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index e54a01b44c5bad..ec823ae52c6f95 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -5004,6 +5004,10 @@ datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us, result_seconds = utc_to_seconds(year, month, day, hour, minute, second); + if (result_seconds == -1 && PyErr_Occurred()) { + return NULL; + } + /* Probe max_fold_seconds to detect a fold. */ probe_seconds = local(epoch + timet - max_fold_seconds); if (probe_seconds == -1) From 93d9b782ccc670b1c162e7eed1dcccc82135251d Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 15 May 2022 23:27:54 -0700 Subject: [PATCH 185/237] gh-87670: Add web.archive redirects from effbot (GH-92816) (cherry picked from commit 3ed1cae9ed9d1f0dd9d68da4b30b731fdf6be768) Co-authored-by: Stanley <46876382+slateny@users.noreply.github.com> --- Doc/whatsnew/2.5.rst | 4 ++-- Doc/whatsnew/2.7.rst | 2 +- Doc/whatsnew/3.2.rst | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Doc/whatsnew/2.5.rst b/Doc/whatsnew/2.5.rst index 4e85abaea75535..5816380e102f99 100644 --- a/Doc/whatsnew/2.5.rst +++ b/Doc/whatsnew/2.5.rst @@ -1767,7 +1767,7 @@ included. The rest of this section will provide a brief overview of using ElementTree. Full documentation for ElementTree is available at -http://effbot.org/zone/element-index.htm. +https://web.archive.org/web/20201124024954/http://effbot.org/zone/element-index.htm. ElementTree represents an XML document as a tree of element nodes. The text content of the document is stored as the :attr:`text` and :attr:`tail` @@ -1865,7 +1865,7 @@ read the package's official documentation for more details. .. seealso:: - http://effbot.org/zone/element-index.htm + https://web.archive.org/web/20201124024954/http://effbot.org/zone/element-index.htm Official documentation for ElementTree. .. ====================================================================== diff --git a/Doc/whatsnew/2.7.rst b/Doc/whatsnew/2.7.rst index abb65222ddd3d0..6d704586cd0945 100644 --- a/Doc/whatsnew/2.7.rst +++ b/Doc/whatsnew/2.7.rst @@ -2089,7 +2089,7 @@ version 1.3. Some of the new features are: Fredrik Lundh develops ElementTree and produced the 1.3 version; you can read his article describing 1.3 at -http://effbot.org/zone/elementtree-13-intro.htm. +https://web.archive.org/web/20200703234532/http://effbot.org/zone/elementtree-13-intro.htm. Florent Xicluna updated the version included with Python, after discussions on python-dev and in :issue:`6472`.) diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst index 840cb061129b7f..ec01a70f8ae0af 100644 --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -744,7 +744,8 @@ Two methods have been deprecated: * :meth:`xml.etree.ElementTree.getiterator` use ``Element.iter`` instead. For details of the update, see `Introducing ElementTree -`_ on Fredrik Lundh's website. +`_ +on Fredrik Lundh's website. (Contributed by Florent Xicluna and Fredrik Lundh, :issue:`6472`.) From cfb9248cd4adb2ef4309e7ddb406cab5ce6edffa Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 16 May 2022 19:53:38 +0300 Subject: [PATCH 186/237] Speedup: build docs in parallel (GH-92733) (GH-92850) (cherry picked from commit a487623c6b784847a8a1e47b4597b0ae2b8def87) --- .github/workflows/doc.yml | 2 +- Doc/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index a57552b07905f4..36b9f9f1d3497f 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -37,7 +37,7 @@ jobs: - name: 'Install build dependencies' run: make -C Doc/ PYTHON=../python venv - name: 'Build documentation' - run: xvfb-run make -C Doc/ PYTHON=../python SPHINXOPTS="-q -W --keep-going -j4" doctest html suspicious + run: xvfb-run make -C Doc/ PYTHON=../python SPHINXOPTS="-q -W --keep-going" doctest html suspicious - name: 'Upload' uses: actions/upload-artifact@v3 with: diff --git a/Doc/Makefile b/Doc/Makefile index 24528a1c4f3269..939498e548a069 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -17,7 +17,7 @@ SPHINXERRORHANDLING = -W PAPEROPT_a4 = -D latex_elements.papersize=a4paper PAPEROPT_letter = -D latex_elements.papersize=letterpaper -ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees $(PAPEROPT_$(PAPER)) \ +ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees $(PAPEROPT_$(PAPER)) -j auto \ $(SPHINXOPTS) $(SPHINXERRORHANDLING) . build/$(BUILDER) $(SOURCES) .PHONY: help build html htmlhelp latex text texinfo changes linkcheck \ From e29ce9a5f111270163a047b50ea55af6cad89838 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 16 May 2022 09:54:01 -0700 Subject: [PATCH 187/237] gh-92530: Fix an issue that occurred after interrupting threading.Condition.notify (GH-92534) (GH-92830) If Condition.notify() was interrupted just after it released the waiter lock, but before removing it from the queue, the following calls of notify() failed with RuntimeError: cannot release un-acquired lock. (cherry picked from commit 70af994fee7c0850ae859727d9468a5f29375a38) Co-authored-by: Serhiy Storchaka --- Lib/threading.py | 21 ++++++++++++------- ...2-05-09-09-28-02.gh-issue-92530.M4Q1RS.rst | 2 ++ 2 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-05-09-09-28-02.gh-issue-92530.M4Q1RS.rst diff --git a/Lib/threading.py b/Lib/threading.py index 2d8974291360d1..668126523d500f 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -368,14 +368,21 @@ def notify(self, n=1): """ if not self._is_owned(): raise RuntimeError("cannot notify on un-acquired lock") - all_waiters = self._waiters - waiters_to_notify = _deque(_islice(all_waiters, n)) - if not waiters_to_notify: - return - for waiter in waiters_to_notify: - waiter.release() + waiters = self._waiters + while waiters and n > 0: + waiter = waiters[0] + try: + waiter.release() + except RuntimeError: + # gh-92530: The previous call of notify() released the lock, + # but was interrupted before removing it from the queue. + # It can happen if a signal handler raises an exception, + # like CTRL+C which raises KeyboardInterrupt. + pass + else: + n -= 1 try: - all_waiters.remove(waiter) + waiters.remove(waiter) except ValueError: pass diff --git a/Misc/NEWS.d/next/Library/2022-05-09-09-28-02.gh-issue-92530.M4Q1RS.rst b/Misc/NEWS.d/next/Library/2022-05-09-09-28-02.gh-issue-92530.M4Q1RS.rst new file mode 100644 index 00000000000000..8bb8ca0488c962 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-05-09-09-28-02.gh-issue-92530.M4Q1RS.rst @@ -0,0 +1,2 @@ +Fix an issue that occurred after interrupting +:func:`threading.Condition.notify`. From 006b302beb68a7b3cee11e34dcee3c20673b5399 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 16 May 2022 09:54:40 -0700 Subject: [PATCH 188/237] gh-80143: Add clarification for escape characters (GH-92292) (GH-92629) (cherry picked from commit 549567c6e70da4846c105a18a1a89e7dd09680d7) Co-authored-by: slateny <46876382+slateny@users.noreply.github.com> --- Doc/reference/lexical_analysis.rst | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index d9e2cead958c95..0dad31fd370e25 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -480,9 +480,11 @@ declaration is given in the source file; see section :ref:`encodings`. In plain English: Both types of literals can be enclosed in matching single quotes (``'``) or double quotes (``"``). They can also be enclosed in matching groups of three single or double quotes (these are generally referred to as -*triple-quoted strings*). The backslash (``\``) character is used to escape -characters that otherwise have a special meaning, such as newline, backslash -itself, or the quote character. +*triple-quoted strings*). The backslash (``\``) character is used to give special +meaning to otherwise ordinary characters like ``n``, which means 'newline' when +escaped (``\n``). It can also be used to escape characters that otherwise have a +special meaning, such as newline, backslash itself, or the quote character. +See :ref:`escape sequences ` below for examples. .. index:: single: b'; bytes literal @@ -541,6 +543,8 @@ retained), except that three unescaped quotes in a row terminate the literal. ( single: \u; escape sequence single: \U; escape sequence +.. _escape-sequences: + Unless an ``'r'`` or ``'R'`` prefix is present, escape sequences in string and bytes literals are interpreted according to rules similar to those used by Standard C. The recognized escape sequences are: From add8820df87958ca584c840ffbe436c5577e6533 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 16 May 2022 18:54:47 -0700 Subject: [PATCH 189/237] Fix NULL test in _testinternalcapi (GH-92861) (cherry picked from commit 702e0da000bf28aa20cb7f3893b575d977506495) Co-authored-by: Dennis Sweeney <36520290+sweeneyde@users.noreply.github.com> --- Modules/_testinternalcapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index d5616fd59c6e50..75e14efb7eb152 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -292,7 +292,7 @@ check_edit_cost(const char *a, const char *b, Py_ssize_t expected) goto exit; } b_obj = PyUnicode_FromString(b); - if (a_obj == NULL) { + if (b_obj == NULL) { goto exit; } Py_ssize_t result = _Py_UTF8_Edit_Cost(a_obj, b_obj, -1); From 009aeb6bb689aadf954d8bebaba4c78acd571cbe Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 17 May 2022 21:16:58 -0700 Subject: [PATCH 190/237] bpo-39829: Fix `__len__()` is called twice in list() constructor (GH-31816) (cherry picked from commit 2153daf0a02a598ed5df93f2f224c1ab2a2cca0d) This patch fixes gh-87740 too. Co-authored-by: Crowthebird <78076854+thatbirdguythatuknownot@users.noreply.github.com> --- Misc/ACKS | 1 + .../2022-03-11-09-39-01.bpo-39829.mlW3Su.rst | 1 + Objects/listobject.c | 29 ++++++++----------- 3 files changed, 14 insertions(+), 17 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-03-11-09-39-01.bpo-39829.mlW3Su.rst diff --git a/Misc/ACKS b/Misc/ACKS index 889bf8aeaea1ac..b83f99956de0b1 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1332,6 +1332,7 @@ William Park Claude Paroz Heikki Partanen Harri Pasanen +Jeremiah Gabriel Pascual Gaël Pasgrimaud Feanil Patel Ashish Nitin Patil diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-11-09-39-01.bpo-39829.mlW3Su.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-11-09-39-01.bpo-39829.mlW3Su.rst new file mode 100644 index 00000000000000..1f3d945188a32a --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-11-09-39-01.bpo-39829.mlW3Su.rst @@ -0,0 +1 @@ +Removed the ``__len__()`` call when initializing a list and moved initializing to ``list_extend``. Patch by Jeremiah Pascual. diff --git a/Objects/listobject.c b/Objects/listobject.c index d3bc5766df7a0b..7f37b7386051d0 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -863,7 +863,6 @@ list_extend(PyListObject *self, PyObject *iterable) PyObject *it; /* iter(v) */ Py_ssize_t m; /* size of self */ Py_ssize_t n; /* guess for size of iterable */ - Py_ssize_t mn; /* m + n */ Py_ssize_t i; PyObject *(*iternext)(PyObject *); @@ -887,7 +886,13 @@ list_extend(PyListObject *self, PyObject *iterable) /* It should not be possible to allocate a list large enough to cause an overflow on any relevant platform */ assert(m < PY_SSIZE_T_MAX - n); - if (list_resize(self, m + n) < 0) { + if (self->ob_item == NULL) { + if (list_preallocate_exact(self, n) < 0) { + return NULL; + } + Py_SET_SIZE(self, n); + } + else if (list_resize(self, m + n) < 0) { Py_DECREF(iterable); return NULL; } @@ -926,10 +931,13 @@ list_extend(PyListObject *self, PyObject *iterable) * eventually run out of memory during the loop. */ } + else if (self->ob_item == NULL) { + if (n && list_preallocate_exact(self, n) < 0) + goto error; + } else { - mn = m + n; /* Make room. */ - if (list_resize(self, mn) < 0) + if (list_resize(self, m + n) < 0) goto error; /* Make the list sane again. */ Py_SET_SIZE(self, m); @@ -2717,19 +2725,6 @@ list___init___impl(PyListObject *self, PyObject *iterable) (void)_list_clear(self); } if (iterable != NULL) { - if (_PyObject_HasLen(iterable)) { - Py_ssize_t iter_len = PyObject_Size(iterable); - if (iter_len == -1) { - if (!PyErr_ExceptionMatches(PyExc_TypeError)) { - return -1; - } - PyErr_Clear(); - } - if (iter_len > 0 && self->ob_item == NULL - && list_preallocate_exact(self, iter_len)) { - return -1; - } - } PyObject *rv = list_extend(self, iterable); if (rv == NULL) return -1; From 1815d8e64fd0bf9fc5fadc2af928a60e380a5c06 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 18 May 2022 02:00:00 -0700 Subject: [PATCH 191/237] gh-91755: Document Py_IncRef and Py_DecRef as C functions (GH-91805) Co-authored-by: Erlend Egeberg Aasland Co-authored-by: Jelle Zijlstra (cherry picked from commit 58a3d28039863b014f57a1ac93b51e20920ebe7b) Co-authored-by: Charlie Zhao --- Doc/c-api/refcounting.rst | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Doc/c-api/refcounting.rst b/Doc/c-api/refcounting.rst index 391907c8c2976a..738bd77e9ce42f 100644 --- a/Doc/c-api/refcounting.rst +++ b/Doc/c-api/refcounting.rst @@ -109,11 +109,17 @@ objects. It is a good idea to use this macro whenever decrementing the reference count of an object that might be traversed during garbage collection. +.. c:function:: void Py_IncRef(PyObject *o) + + Increment the reference count for object *o*. A function version of :c:func:`Py_XINCREF`. + It can be used for runtime dynamic embedding of Python. + + +.. c:function:: void Py_DecRef(PyObject *o) + + Decrement the reference count for object *o*. A function version of :c:func:`Py_XDECREF`. + It can be used for runtime dynamic embedding of Python. -The following functions are for runtime dynamic embedding of Python: -``Py_IncRef(PyObject *o)``, ``Py_DecRef(PyObject *o)``. They are -simply exported function versions of :c:func:`Py_XINCREF` and -:c:func:`Py_XDECREF`, respectively. The following functions or macros are only for use within the interpreter core: :c:func:`_Py_Dealloc`, :c:func:`_Py_ForgetReference`, :c:func:`_Py_NewReference`, From 94e21cf2299c7a2b6fdb4ddc6f1f2a879a83d21f Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 18 May 2022 05:05:24 -0700 Subject: [PATCH 192/237] gh-92780: Improve sqlite3.Connection.create_collation docs (GH-92790) Co-authored-by: Alex Waygood (cherry picked from commit 7ee19e27150a72eec9e6a076792e3c3ae8bcffbd) Co-authored-by: Erlend Egeberg Aasland --- Doc/library/sqlite3.rst | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 3fac2db174c338..a430144bd5e750 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -436,22 +436,19 @@ Connection Objects .. method:: create_collation(name, callable) - Creates a collation with the specified *name* and *callable*. The callable will - be passed two string arguments. It should return -1 if the first is ordered - lower than the second, 0 if they are ordered equal and 1 if the first is ordered - higher than the second. Note that this controls sorting (ORDER BY in SQL) so - your comparisons don't affect other SQL operations. + Create a collation named *name* using the collating function *callable*. + *callable* is passed two :class:`string ` arguments, + and it should return an :class:`integer `: - Note that the callable will get its parameters as Python bytestrings, which will - normally be encoded in UTF-8. + * ``1`` if the first is ordered higher than the second + * ``-1`` if the first is ordered lower than the second + * ``0`` if they are ordered equal - The following example shows a custom collation that sorts "the wrong way": + The following example shows a reverse sorting collation: .. literalinclude:: ../includes/sqlite3/collation_reverse.py - To remove a collation, call ``create_collation`` with ``None`` as callable:: - - con.create_collation("reverse", None) + Remove a collation function by setting *callable* to :const:`None`. .. method:: interrupt() From ed75d2183f9084583e2ebe9229c52711d4a62f1e Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 18 May 2022 05:49:15 -0700 Subject: [PATCH 193/237] bpo-40838: document `getdoc`, `getmodule`, `getsourcefile` in `inspect` returns `None` (GH-30575) Co-authored-by: Alex Waygood Co-authored-by: Jelle Zijlstra (cherry picked from commit b86d783a4eff96306f315acf9a6f1aca85d47fc3) Co-authored-by: Nikita Sobolev --- Doc/library/inspect.rst | 7 +++++-- .../Documentation/2022-01-13-16-03-15.bpo-40838.k3NVCf.rst | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2022-01-13-16-03-15.bpo-40838.k3NVCf.rst diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index d7ef2adf7281b6..44553afc33b75c 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -482,6 +482,7 @@ Retrieving source code If the documentation string for an object is not provided and the object is a class, a method, a property or a descriptor, retrieve the documentation string from the inheritance hierarchy. + Return ``None`` if the documentation string is invalid or missing. .. versionchanged:: 3.5 Documentation strings are now inherited if not overridden. @@ -505,12 +506,14 @@ Retrieving source code .. function:: getmodule(object) - Try to guess which module an object was defined in. + Try to guess which module an object was defined in. Return ``None`` + if the module cannot be determined. .. function:: getsourcefile(object) - Return the name of the Python source file in which an object was defined. This + Return the name of the Python source file in which an object was defined + or ``None`` if no way can be identified to get the source. This will fail with a :exc:`TypeError` if the object is a built-in module, class, or function. diff --git a/Misc/NEWS.d/next/Documentation/2022-01-13-16-03-15.bpo-40838.k3NVCf.rst b/Misc/NEWS.d/next/Documentation/2022-01-13-16-03-15.bpo-40838.k3NVCf.rst new file mode 100644 index 00000000000000..0f071ab64dbecc --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-01-13-16-03-15.bpo-40838.k3NVCf.rst @@ -0,0 +1,2 @@ +Document that :func:`inspect.getdoc`, :func:`inspect.getmodule`, and +:func:`inspect.getsourcefile` might return ``None``. From 17524b084b565b321b4671f50a62864ea907b24f Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 18 May 2022 14:30:00 -0700 Subject: [PATCH 194/237] gh-92812: Align ArgumentParser.add_subparsers() docs with argument spec (GH-92814) (cherry picked from commit f2d994da104eed38f9e110e7d8f37fa6d845b207) Co-authored-by: 180909 <734461790@qq.com> --- Doc/library/argparse.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index e8e54d6c58df36..d96f17b80a5f0f 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -1615,7 +1615,7 @@ Sub-commands .. method:: ArgumentParser.add_subparsers([title], [description], [prog], \ [parser_class], [action], \ - [option_string], [dest], [required], \ + [option_strings], [dest], [required], \ [help], [metavar]) Many programs split up their functionality into a number of sub-commands, From 3e534b464af77cade6295d1f18619f33c8b7ba70 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 19 May 2022 02:40:39 -0700 Subject: [PATCH 195/237] Doc: amend ssl.PROTOCOL_SSLv2 and ssl.PROTOCOL_SSLv3 wording (GH-92634) (cherry picked from commit 41638967a0e0bf1114c9bba9454d081605b49009) Co-authored-by: Jan Brasna <1784648+janbrasna@users.noreply.github.com> --- Doc/library/ssl.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 19d983bcfe28df..afb3e356db89ae 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -714,7 +714,7 @@ Constants Selects SSL version 2 as the channel encryption protocol. This protocol is not available if OpenSSL is compiled with the - ``OPENSSL_NO_SSL2`` flag. + ``no-ssl2`` option. .. warning:: @@ -728,8 +728,8 @@ Constants Selects SSL version 3 as the channel encryption protocol. - This protocol is not be available if OpenSSL is compiled with the - ``OPENSSL_NO_SSLv3`` flag. + This protocol is not available if OpenSSL is compiled with the + ``no-ssl3`` option. .. warning:: From 56c8d7cc83fbc944b78b7685828f1990fbd017da Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 19 May 2022 02:52:41 -0700 Subject: [PATCH 196/237] gh-92670: Skip test_shutil.TestCopy.test_copyfile_nonexistent_dir on AIX (GH-92718) (cherry picked from commit 654032ac5f6982b36d45e024037f37fb65166aed) Co-authored-by: Ayappan Perumal --- Lib/test/test_shutil.py | 4 ++++ .../next/Tests/2022-05-12-05-51-06.gh-issue-92670.7L43Z_.rst | 3 +++ 2 files changed, 7 insertions(+) create mode 100644 Misc/NEWS.d/next/Tests/2022-05-12-05-51-06.gh-issue-92670.7L43Z_.rst diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index 7669b94ac35a68..f1d8f5a8b637f2 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -1273,6 +1273,10 @@ def test_copyfile_same_file(self): self.assertEqual(read_file(src_file), 'foo') @unittest.skipIf(MACOS or SOLARIS or _winapi, 'On MACOS, Solaris and Windows the errors are not confusing (though different)') + # gh-92670: The test uses a trailing slash to force the OS consider + # the path as a directory, but on AIX the trailing slash has no effect + # and is considered as a file. + @unittest.skipIf(AIX, 'Not valid on AIX, see gh-92670') def test_copyfile_nonexistent_dir(self): # Issue 43219 src_dir = self.mkdtemp() diff --git a/Misc/NEWS.d/next/Tests/2022-05-12-05-51-06.gh-issue-92670.7L43Z_.rst b/Misc/NEWS.d/next/Tests/2022-05-12-05-51-06.gh-issue-92670.7L43Z_.rst new file mode 100644 index 00000000000000..c1349519e7c37c --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-05-12-05-51-06.gh-issue-92670.7L43Z_.rst @@ -0,0 +1,3 @@ +Skip ``test_shutil.TestCopy.test_copyfile_nonexistent_dir`` test on AIX as the test uses a trailing +slash to force the OS consider the path as a directory, but on AIX the +trailing slash has no effect and is considered as a file. From 4e289e20e28489a76a534fd5a6f4b2869eb3af0c Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 19 May 2022 08:19:53 -0700 Subject: [PATCH 197/237] gh-92417: Update docs and examples of doctest.IGNORE_EXCEPTION_DETAIL for Py>=3 (GH-92502) (GH-92963) (cherry picked from commit 97b9c1096feff77a564787ef520cc7d4e1d1c45f) --- Doc/library/doctest.rst | 48 ++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst index 59091e48d309f1..dbb54c99133f39 100644 --- a/Doc/library/doctest.rst +++ b/Doc/library/doctest.rst @@ -564,41 +564,35 @@ doctest decides whether actual output matches an example's expected output: .. data:: IGNORE_EXCEPTION_DETAIL - When specified, an example that expects an exception passes if an exception of - the expected type is raised, even if the exception detail does not match. For - example, an example expecting ``ValueError: 42`` will pass if the actual - exception raised is ``ValueError: 3*14``, but will fail, e.g., if - :exc:`TypeError` is raised. + When specified, doctests expecting exceptions pass so long as an exception + of the expected type is raised, even if the details + (message and fully-qualified exception name) don't match. - It will also ignore the module name used in Python 3 doctest reports. Hence - both of these variations will work with the flag specified, regardless of - whether the test is run under Python 2.7 or Python 3.2 (or later versions):: + For example, an example expecting ``ValueError: 42`` will pass if the actual + exception raised is ``ValueError: 3*14``, but will fail if, say, a + :exc:`TypeError` is raised instead. + It will also ignore any fully-qualified name included before the + exception class, which can vary between implementations and versions + of Python and the code/libraries in use. + Hence, all three of these variations will work with the flag specified: - >>> raise CustomError('message') + .. code-block:: pycon + + >>> raise Exception('message') Traceback (most recent call last): - CustomError: message + Exception: message - >>> raise CustomError('message') + >>> raise Exception('message') Traceback (most recent call last): - my_module.CustomError: message + builtins.Exception: message - Note that :const:`ELLIPSIS` can also be used to ignore the - details of the exception message, but such a test may still fail based - on whether or not the module details are printed as part of the - exception name. Using :const:`IGNORE_EXCEPTION_DETAIL` and the details - from Python 2.3 is also the only clear way to write a doctest that doesn't - care about the exception detail yet continues to pass under Python 2.3 or - earlier (those releases do not support :ref:`doctest directives - ` and ignore them as irrelevant comments). For example:: - - >>> (1, 2)[3] = 'moo' + >>> raise Exception('message') Traceback (most recent call last): - File "", line 1, in - TypeError: object doesn't support item assignment + __main__.Exception: message - passes under Python 2.3 and later Python versions with the flag specified, - even though the detail - changed in Python 2.4 to say "does not" instead of "doesn't". + Note that :const:`ELLIPSIS` can also be used to ignore the + details of the exception message, but such a test may still fail based + on whether the module name is present or matches exactly. .. versionchanged:: 3.2 :const:`IGNORE_EXCEPTION_DETAIL` now also ignores any information relating From fb566cacb3019bce3ce27158e4edcf3501086775 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 19 May 2022 08:32:54 -0700 Subject: [PATCH 198/237] bpo-45393: help() on operator precedence has misleading entries (GH-31246) (GH-92966) (cherry picked from commit fb082c2fc5a925085b179e63ca10b7f60b356d2f) Co-authored-by: Zackery Spytz --- Doc/reference/expressions.rst | 4 ++-- .../next/Library/2022-02-09-23-44-27.bpo-45393.9v5Y8U.rst | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-02-09-23-44-27.bpo-45393.9v5Y8U.rst diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index f77927d86d9d66..1f8b08f70d504e 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -1891,7 +1891,7 @@ precedence and have a left-to-right chaining feature as described in the | ``x[index]``, ``x[index:index]``, | Subscription, slicing, | | ``x(arguments...)``, ``x.attribute`` | call, attribute reference | +-----------------------------------------------+-------------------------------------+ -| :keyword:`await` ``x`` | Await expression | +| :keyword:`await x ` | Await expression | +-----------------------------------------------+-------------------------------------+ | ``**`` | Exponentiation [#]_ | +-----------------------------------------------+-------------------------------------+ @@ -1915,7 +1915,7 @@ precedence and have a left-to-right chaining feature as described in the | :keyword:`is`, :keyword:`is not`, ``<``, | tests and identity tests | | ``<=``, ``>``, ``>=``, ``!=``, ``==`` | | +-----------------------------------------------+-------------------------------------+ -| :keyword:`not` ``x`` | Boolean NOT | +| :keyword:`not x ` | Boolean NOT | +-----------------------------------------------+-------------------------------------+ | :keyword:`and` | Boolean AND | +-----------------------------------------------+-------------------------------------+ diff --git a/Misc/NEWS.d/next/Library/2022-02-09-23-44-27.bpo-45393.9v5Y8U.rst b/Misc/NEWS.d/next/Library/2022-02-09-23-44-27.bpo-45393.9v5Y8U.rst new file mode 100644 index 00000000000000..0a239b07d76bd1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-02-09-23-44-27.bpo-45393.9v5Y8U.rst @@ -0,0 +1,2 @@ +Fix the formatting for ``await x`` and ``not x`` in the operator precedence +table when using the :func:`help` system. From ebf3f12c389c6d9cedf54c5daac065de3ef53256 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 19 May 2022 08:44:31 -0700 Subject: [PATCH 199/237] gh-92417: `socket` docs: remove references to Python <3.3 (GH-92544) (GH-92969) (cherry picked from commit 639b62c9c479e38a6f91a80b261097574a1e7ac7) Co-authored-by: Alex Waygood --- Doc/library/socket.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 7ce8e5b0d80381..4af78e415f3d71 100755 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -233,9 +233,9 @@ resolution and/or the host configuration. For deterministic behavior use a numeric address in *host* portion. All errors raise exceptions. The normal exceptions for invalid argument types -and out-of-memory conditions can be raised; starting from Python 3.3, errors +and out-of-memory conditions can be raised. Errors related to socket or address semantics raise :exc:`OSError` or one of its -subclasses (they used to raise :exc:`socket.error`). +subclasses. Non-blocking mode is supported through :meth:`~socket.setblocking`. A generalization of this based on timeouts is supported through From 93ebac7a79c055b6122ef086000b456361388dd9 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 19 May 2022 08:45:30 -0700 Subject: [PATCH 200/237] gh-92417: `fractions`, `decimal`: Improve docs for alternative constructor methods (GH-92421) (GH-92971) Co-authored-by: Ezio Melotti (cherry picked from commit 090df844ea16af3a5df79aba2b9c89ac6a31ba06) Co-authored-by: Alex Waygood --- Doc/library/decimal.rst | 5 +++-- Doc/library/fractions.rst | 12 ++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index e759c5cf23b9e7..47627c02561b94 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -571,9 +571,10 @@ Decimal objects >>> Decimal(321).exp() Decimal('2.561702493119680037517373933E+139') - .. method:: from_float(f) + .. classmethod:: from_float(f) - Classmethod that converts a float to a decimal number, exactly. + Alternative constructor that only accepts instances of :class:`float` or + :class:`int`. Note `Decimal.from_float(0.1)` is not the same as `Decimal('0.1')`. Since 0.1 is not exactly representable in binary floating point, the diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst index a4d006eb58ffeb..0f7940ae68bef4 100644 --- a/Doc/library/fractions.rst +++ b/Doc/library/fractions.rst @@ -105,10 +105,10 @@ another rational number, or from a string. .. versionadded:: 3.8 - .. method:: from_float(flt) + .. classmethod:: from_float(flt) - This class method constructs a :class:`Fraction` representing the exact - value of *flt*, which must be a :class:`float`. Beware that + Alternative constructor which only accepts instances of + :class:`float` or :class:`numbers.Integral`. Beware that ``Fraction.from_float(0.3)`` is not the same value as ``Fraction(3, 10)``. .. note:: @@ -117,10 +117,10 @@ another rational number, or from a string. :class:`Fraction` instance directly from a :class:`float`. - .. method:: from_decimal(dec) + .. classmethod:: from_decimal(dec) - This class method constructs a :class:`Fraction` representing the exact - value of *dec*, which must be a :class:`decimal.Decimal` instance. + Alternative constructor which only accepts instances of + :class:`decimal.Decimal` or :class:`numbers.Integral`. .. note:: From 3d47035686f34dee77e40738780ab2a9be3c3989 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 19 May 2022 08:49:13 -0700 Subject: [PATCH 201/237] gh-92417: `subprocess` docs: remove note on compatibility with Python <3.5 (GH-92538) (GH-92973) (cherry picked from commit 84b86000e2bc32b0fbb6dfb6445a7ffc882067d2) Co-authored-by: Alex Waygood --- Doc/library/subprocess.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index 4d3312077bbd09..d0f8864493ed02 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -33,9 +33,6 @@ The recommended approach to invoking subprocesses is to use the :func:`run` function for all use cases it can handle. For more advanced use cases, the underlying :class:`Popen` interface can be used directly. -The :func:`run` function was added in Python 3.5; if you need to retain -compatibility with older versions, see the :ref:`call-function-trio` section. - .. function:: run(args, *, stdin=None, input=None, stdout=None, stderr=None,\ capture_output=False, shell=False, cwd=None, timeout=None, \ From 5d7f3dc3dca506cf23c7a502c5083b44cf759a1c Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 19 May 2022 08:57:46 -0700 Subject: [PATCH 202/237] bpo-46879: Fix incorrect sphinx object names in doc (GH-31615) (GH-92975) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 2cdd57f119e3b85f1bfd28c7ff040e0d9bcaf115) Co-authored-by: Łukasz Langa Co-authored-by: Martin Fischer --- Doc/library/asyncio-subprocess.rst | 4 ++++ Doc/library/multiprocessing.rst | 1 + Doc/library/xml.etree.elementtree.rst | 2 ++ 3 files changed, 7 insertions(+) diff --git a/Doc/library/asyncio-subprocess.rst b/Doc/library/asyncio-subprocess.rst index e5000532a895dd..28d0b21e8180b6 100644 --- a/Doc/library/asyncio-subprocess.rst +++ b/Doc/library/asyncio-subprocess.rst @@ -124,6 +124,7 @@ Constants ========= .. data:: asyncio.subprocess.PIPE + :module: Can be passed to the *stdin*, *stdout* or *stderr* parameters. @@ -137,11 +138,13 @@ Constants attributes will point to :class:`StreamReader` instances. .. data:: asyncio.subprocess.STDOUT + :module: Special value that can be used as the *stderr* argument and indicates that standard error should be redirected into standard output. .. data:: asyncio.subprocess.DEVNULL + :module: Special value that can be used as the *stdin*, *stdout* or *stderr* argument to process creation functions. It indicates that the special file @@ -157,6 +160,7 @@ wrapper that allows communicating with subprocesses and watching for their completion. .. class:: asyncio.subprocess.Process + :module: An object that wraps OS processes created by the :func:`create_subprocess_exec` and :func:`create_subprocess_shell` diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 096e6492cd42e8..de8f9718337d77 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -1648,6 +1648,7 @@ different machines. A manager object controls a server process which manages proxies. .. function:: multiprocessing.Manager() + :module: Returns a started :class:`~multiprocessing.managers.SyncManager` object which can be used for sharing objects between processes. The returned manager diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index e3932bc9e659fe..2fe0d2e082fb3a 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -826,6 +826,7 @@ Functions ^^^^^^^^^ .. function:: xml.etree.ElementInclude.default_loader( href, parse, encoding=None) + :module: Default loader. This default loader reads an included resource from disk. *href* is a URL. *parse* is for parse mode either "xml" or "text". *encoding* @@ -837,6 +838,7 @@ Functions .. function:: xml.etree.ElementInclude.include( elem, loader=None, base_url=None, \ max_depth=6) + :module: This function expands XInclude directives. *elem* is the root element. *loader* is an optional resource loader. If omitted, it defaults to :func:`default_loader`. From c146525844b716e73386205ee8bed9268cc73fc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Thu, 19 May 2022 21:16:57 +0200 Subject: [PATCH 203/237] [3.10] bpo-28249: fix `lineno` location for empty `DocTest` instances (GH-30498) (#92981) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 8db2b3b6878aba9f12844526bce966b7eed81aee) Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> Co-authored-by: Łukasz Langa Co-authored-by: Nikita Sobolev --- Lib/doctest.py | 14 ++++-- Lib/test/doctest_lineno.py | 50 +++++++++++++++++++ Lib/test/test_doctest.py | 23 ++++++++- .../2022-01-09-14-23-00.bpo-28249.4dzB80.rst | 2 + 4 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 Lib/test/doctest_lineno.py create mode 100644 Misc/NEWS.d/next/Library/2022-01-09-14-23-00.bpo-28249.4dzB80.rst diff --git a/Lib/doctest.py b/Lib/doctest.py index 67cc34347bdf7a..37b31cfbb2c973 100644 --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -1085,19 +1085,21 @@ def _get_test(self, obj, name, module, globs, source_lines): def _find_lineno(self, obj, source_lines): """ - Return a line number of the given object's docstring. Note: - this method assumes that the object has a docstring. + Return a line number of the given object's docstring. + + Returns `None` if the given object does not have a docstring. """ lineno = None + docstring = getattr(obj, '__doc__', None) # Find the line number for modules. - if inspect.ismodule(obj): + if inspect.ismodule(obj) and docstring is not None: lineno = 0 # Find the line number for classes. # Note: this could be fooled if a class is defined multiple # times in a single file. - if inspect.isclass(obj): + if inspect.isclass(obj) and docstring is not None: if source_lines is None: return None pat = re.compile(r'^\s*class\s*%s\b' % @@ -1109,7 +1111,9 @@ def _find_lineno(self, obj, source_lines): # Find the line number for functions & methods. if inspect.ismethod(obj): obj = obj.__func__ - if inspect.isfunction(obj): obj = obj.__code__ + if inspect.isfunction(obj) and getattr(obj, '__doc__', None): + # We don't use `docstring` var here, because `obj` can be changed. + obj = obj.__code__ if inspect.istraceback(obj): obj = obj.tb_frame if inspect.isframe(obj): obj = obj.f_code if inspect.iscode(obj): diff --git a/Lib/test/doctest_lineno.py b/Lib/test/doctest_lineno.py new file mode 100644 index 00000000000000..be198513a1502c --- /dev/null +++ b/Lib/test/doctest_lineno.py @@ -0,0 +1,50 @@ +# This module is used in `test_doctest`. +# It must not have a docstring. + +def func_with_docstring(): + """Some unrelated info.""" + + +def func_without_docstring(): + pass + + +def func_with_doctest(): + """ + This function really contains a test case. + + >>> func_with_doctest.__name__ + 'func_with_doctest' + """ + return 3 + + +class ClassWithDocstring: + """Some unrelated class information.""" + + +class ClassWithoutDocstring: + pass + + +class ClassWithDoctest: + """This class really has a test case in it. + + >>> ClassWithDoctest.__name__ + 'ClassWithDoctest' + """ + + +class MethodWrapper: + def method_with_docstring(self): + """Method with a docstring.""" + + def method_without_docstring(self): + pass + + def method_with_doctest(self): + """ + This has a doctest! + >>> MethodWrapper.method_with_doctest.__name__ + 'method_with_doctest' + """ diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py index 1098a7b9f471f0..ebd4ad91924cfb 100644 --- a/Lib/test/test_doctest.py +++ b/Lib/test/test_doctest.py @@ -20,6 +20,7 @@ # NOTE: There are some additional tests relating to interaction with # zipimport in the test_zipimport_support test module. +# There are also related tests in `test_doctest2` module. ###################################################################### ## Sample Objects (used by test cases) @@ -455,7 +456,7 @@ def basics(): r""" >>> tests = finder.find(sample_func) >>> print(tests) # doctest: +ELLIPSIS - [] + [] The exact name depends on how test_doctest was invoked, so allow for leading path components. @@ -637,6 +638,26 @@ def basics(): r""" 1 SampleClass.double 1 SampleClass.get +When used with `exclude_empty=False` we are also interested in line numbers +of doctests that are empty. +It used to be broken for quite some time until `bpo-28249`. + + >>> from test import doctest_lineno + >>> tests = doctest.DocTestFinder(exclude_empty=False).find(doctest_lineno) + >>> for t in tests: + ... print('%5s %s' % (t.lineno, t.name)) + None test.doctest_lineno + 22 test.doctest_lineno.ClassWithDocstring + 30 test.doctest_lineno.ClassWithDoctest + None test.doctest_lineno.ClassWithoutDocstring + None test.doctest_lineno.MethodWrapper + 39 test.doctest_lineno.MethodWrapper.method_with_docstring + 45 test.doctest_lineno.MethodWrapper.method_with_doctest + None test.doctest_lineno.MethodWrapper.method_without_docstring + 4 test.doctest_lineno.func_with_docstring + 12 test.doctest_lineno.func_with_doctest + None test.doctest_lineno.func_without_docstring + Turning off Recursion ~~~~~~~~~~~~~~~~~~~~~ DocTestFinder can be told not to look for tests in contained objects diff --git a/Misc/NEWS.d/next/Library/2022-01-09-14-23-00.bpo-28249.4dzB80.rst b/Misc/NEWS.d/next/Library/2022-01-09-14-23-00.bpo-28249.4dzB80.rst new file mode 100644 index 00000000000000..b5f1312d768669 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-01-09-14-23-00.bpo-28249.4dzB80.rst @@ -0,0 +1,2 @@ +Set :attr:`doctest.DocTest.lineno` to ``None`` when object does not have +:attr:`__doc__`. From 49526080eb448b750396caf90081ff846e36a36d Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 19 May 2022 15:48:42 -0700 Subject: [PATCH 204/237] gh-92984: Explicitly disable incremental linking for Windows Release and PGO builds (GH-92985) (cherry picked from commit 38feffa09c74d9a853745908b7813903bae33b96) Co-authored-by: David Machaj <46852402+dmachaj@users.noreply.github.com> --- .../next/Windows/2022-05-19-14-01-30.gh-issue-92984.Dsxnlr.rst | 1 + PCbuild/pyproject.props | 1 + 2 files changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Windows/2022-05-19-14-01-30.gh-issue-92984.Dsxnlr.rst diff --git a/Misc/NEWS.d/next/Windows/2022-05-19-14-01-30.gh-issue-92984.Dsxnlr.rst b/Misc/NEWS.d/next/Windows/2022-05-19-14-01-30.gh-issue-92984.Dsxnlr.rst new file mode 100644 index 00000000000000..2d3071b00b7618 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-05-19-14-01-30.gh-issue-92984.Dsxnlr.rst @@ -0,0 +1 @@ +Explicitly disable incremental linking for non-Debug builds diff --git a/PCbuild/pyproject.props b/PCbuild/pyproject.props index d492b71dfbaa3d..5af68b27d4c10f 100644 --- a/PCbuild/pyproject.props +++ b/PCbuild/pyproject.props @@ -18,6 +18,7 @@ true false false + false From 4d363d8989bf79f091bf674701e6066908af788d Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 20 May 2022 02:21:29 -0700 Subject: [PATCH 205/237] Doc: add missing manpage and title references in tkinter docs (GH-29008) - add bind(3tk) manpage markup - add Tcl/Tk book reference markup (cherry picked from commit 0e12781ad9dec6e46ccb85969c0eb7be1ecad81d) Co-authored-by: Rafael Fontenelle --- Doc/library/tkinter.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 37b6a02a31710e..096a343bd95589 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -877,8 +877,9 @@ of the bind method is:: where: sequence - is a string that denotes the target kind of event. (See the bind man page and - page 201 of John Ousterhout's book for details). + is a string that denotes the target kind of event. (See the + :manpage:`bind(3tk)` man page, and page 201 of John Ousterhout's book, + :title-reference:`Tcl and the Tk Toolkit (2nd edition)`, for details). func is a Python function, taking one argument, to be invoked when the event occurs. From 3c2a1e7f4af3c5c54e04dfe9ac3a68d2351b00fb Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 20 May 2022 15:44:07 -0700 Subject: [PATCH 206/237] [3.10] gh-72073: Add Windows case in pathlib.rename (GH-93002) (GH-93029) GH-72073 https://docs.python.org/3.12/library/pathlib.htmlGH-pathlib.Path.rename (cherry picked from commit f51ed04c663417f88e10eeb21dad23250358bafa) Co-authored-by: Stanley <46876382+slateny@users.noreply.github.com> Automerge-Triggered-By: GH:brettcannon --- Doc/library/pathlib.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index f036d8119243a6..004f671b033aea 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -1018,8 +1018,9 @@ call fails (for example because the path doesn't exist). Rename this file or directory to the given *target*, and return a new Path instance pointing to *target*. On Unix, if *target* exists and is a file, - it will be replaced silently if the user has permission. *target* can be - either a string or another path object:: + it will be replaced silently if the user has permission. + On Windows, if *target* exists, :exc:`FileExistsError` will be raised. + *target* can be either a string or another path object:: >>> p = Path('foo') >>> p.open('w').write('some text') From 54b5e4da8a4c6ae527ab238fcd6b9ba0a3ed0fc7 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 21 May 2022 08:10:56 -0700 Subject: [PATCH 207/237] gh-91362: reword pickle docs to account for nested classes (GH-92429) Fixes GH-91362 (cherry picked from commit f9d6c59917435980fbe1b58c57257c45bfed2244) Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com> --- Doc/library/pickle.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst index f7db0e8415f4c7..920df712ea58f7 100644 --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -502,10 +502,10 @@ The following types can be pickled: * tuples, lists, sets, and dictionaries containing only picklable objects; -* functions (built-in and user-defined) defined at the top level of a module - (using :keyword:`def`, not :keyword:`lambda`); +* functions (built-in and user-defined) accessible from the top level of a + module (using :keyword:`def`, not :keyword:`lambda`); -* classes defined at the top level of a module; +* classes accessible from the top level of a module; * instances of such classes whose :attr:`~object.__dict__` or the result of calling :meth:`__getstate__` is picklable (see section :ref:`pickle-inst` for @@ -518,9 +518,9 @@ structure may exceed the maximum recursion depth, a :exc:`RecursionError` will b raised in this case. You can carefully raise this limit with :func:`sys.setrecursionlimit`. -Note that functions (built-in and user-defined) are pickled by fully qualified -name, not by value. [#]_ This means that only the function name is -pickled, along with the name of the module the function is defined in. Neither +Note that functions (built-in and user-defined) are pickled by fully +:term:`qualified name`, not by value. [#]_ This means that only the function name is +pickled, along with the name of the containing module and classes. Neither the function's code, nor any of its function attributes are pickled. Thus the defining module must be importable in the unpickling environment, and the module must contain the named object, otherwise an exception will be raised. [#]_ From 619a67cc0675556065d7bb137727c029fff7d5f8 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 22 May 2022 19:06:54 -0700 Subject: [PATCH 208/237] gh-73137: Added sub-subsection headers for flags in re (GH-93000) Fixes GH-73137 (cherry picked from commit b7a6610bc88dfecdd943e8d2817f7cd6b85fb740) Co-authored-by: Stanley <46876382+slateny@users.noreply.github.com> --- Doc/library/re.rst | 72 +++++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/Doc/library/re.rst b/Doc/library/re.rst index b12ce4b9744f94..fd12241312211d 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -602,40 +602,14 @@ functions are simplified versions of the full featured methods for compiled regular expressions. Most non-trivial applications always use the compiled form. + +Flags +^^^^^ + .. versionchanged:: 3.6 Flag constants are now instances of :class:`RegexFlag`, which is a subclass of :class:`enum.IntFlag`. -.. function:: compile(pattern, flags=0) - - Compile a regular expression pattern into a :ref:`regular expression object - `, which can be used for matching using its - :func:`~Pattern.match`, :func:`~Pattern.search` and other methods, described - below. - - The expression's behaviour can be modified by specifying a *flags* value. - Values can be any of the following variables, combined using bitwise OR (the - ``|`` operator). - - The sequence :: - - prog = re.compile(pattern) - result = prog.match(string) - - is equivalent to :: - - result = re.match(pattern, string) - - but using :func:`re.compile` and saving the resulting regular expression - object for reuse is more efficient when the expression will be used several - times in a single program. - - .. note:: - - The compiled versions of the most recent patterns passed to - :func:`re.compile` and the module-level matching functions are cached, so - programs that use only a few regular expressions at a time needn't worry - about compiling regular expressions. .. data:: A @@ -744,6 +718,41 @@ form. Corresponds to the inline flag ``(?x)``. +Functions +^^^^^^^^^ + +.. function:: compile(pattern, flags=0) + + Compile a regular expression pattern into a :ref:`regular expression object + `, which can be used for matching using its + :func:`~Pattern.match`, :func:`~Pattern.search` and other methods, described + below. + + The expression's behaviour can be modified by specifying a *flags* value. + Values can be any of the following variables, combined using bitwise OR (the + ``|`` operator). + + The sequence :: + + prog = re.compile(pattern) + result = prog.match(string) + + is equivalent to :: + + result = re.match(pattern, string) + + but using :func:`re.compile` and saving the resulting regular expression + object for reuse is more efficient when the expression will be used several + times in a single program. + + .. note:: + + The compiled versions of the most recent patterns passed to + :func:`re.compile` and the module-level matching functions are cached, so + programs that use only a few regular expressions at a time needn't worry + about compiling regular expressions. + + .. function:: search(pattern, string, flags=0) Scan through *string* looking for the first location where the regular expression @@ -975,6 +984,9 @@ form. Clear the regular expression cache. +Exceptions +^^^^^^^^^^ + .. exception:: error(msg, pattern=None, pos=None) Exception raised when a string passed to one of the functions here is not a From 936eefcb820a02e6fad3c8128e89494e6b958717 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 22 May 2022 19:11:58 -0700 Subject: [PATCH 209/237] gh-92994: Clarify importlib "check" example (GH-92995) Fixes GH-92994 (cherry picked from commit e39cd765610c9099da3b5595186ad16223b670b0) Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com> --- Doc/library/importlib.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index c9fb63b75a4718..85c23472e27560 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -1749,6 +1749,9 @@ Checking if a module can be imported If you need to find out if a module can be imported without actually doing the import, then you should use :func:`importlib.util.find_spec`. + +Note that if ``name`` is a submodule (contains a dot), +:func:`importlib.util.find_spec` will import the parent module. :: import importlib.util From c8f1095e0a13c943eeca50802887fce4a9a7decc Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 22 May 2022 22:17:15 -0700 Subject: [PATCH 210/237] gh-89158: Add some REPL secondary prompt markers (GH-93073) This fixes an issue on tutorial/classes.rst section 9.4 where the example "class Warehouse" was truncated when pressing the >>> button to hide the prompts and output. (cherry picked from commit 88f0d0c1e8fdda036f3f64b0048911ba28ce7f06) Co-authored-by: Nicolas Haller --- Doc/tutorial/classes.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst index f44cb0b4e905a9..58b06eb5f25356 100644 --- a/Doc/tutorial/classes.rst +++ b/Doc/tutorial/classes.rst @@ -479,9 +479,9 @@ If the same attribute name occurs in both an instance and in a class, then attribute lookup prioritizes the instance:: >>> class Warehouse: - purpose = 'storage' - region = 'west' - + ... purpose = 'storage' + ... region = 'west' + ... >>> w1 = Warehouse() >>> print(w1.purpose, w1.region) storage west From b15b94de091d184e1f1281af190debaf9b92de78 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 23 May 2022 10:02:15 -0700 Subject: [PATCH 211/237] gh-93010: InvalidHeaderError used but nonexistent (GH-93015) * fix issue 93010 Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> (cherry picked from commit 71abeb0895f7563dc5ac4b4f077a8f87dab57e7a) Co-authored-by: oda-gitso <105083118+oda-gitso@users.noreply.github.com> --- Lib/email/_header_value_parser.py | 2 +- Lib/test/test_email/test_email.py | 22 ++++++++++++------- ...2-05-20-15-52-43.gh-issue-93010.WF-cAc.rst | 1 + 3 files changed, 16 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-05-20-15-52-43.gh-issue-93010.WF-cAc.rst diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py index 8a8fb8bc42a954..e637e6df06612d 100644 --- a/Lib/email/_header_value_parser.py +++ b/Lib/email/_header_value_parser.py @@ -2379,7 +2379,7 @@ def get_section(value): digits += value[0] value = value[1:] if digits[0] == '0' and digits != '0': - section.defects.append(errors.InvalidHeaderError( + section.defects.append(errors.InvalidHeaderDefect( "section number has an invalid leading 0")) section.number = int(digits) section.append(ValueTerminal(digits, 'digits')) diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py index af0ea03fedf0cb..3a5663ac01d0f2 100644 --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -18,24 +18,25 @@ import email.policy from email.charset import Charset -from email.header import Header, decode_header, make_header -from email.parser import Parser, HeaderParser from email.generator import Generator, DecodedGenerator, BytesGenerator +from email.header import Header, decode_header, make_header +from email.headerregistry import HeaderRegistry from email.message import Message from email.mime.application import MIMEApplication from email.mime.audio import MIMEAudio -from email.mime.text import MIMEText -from email.mime.image import MIMEImage from email.mime.base import MIMEBase +from email.mime.image import MIMEImage from email.mime.message import MIMEMessage from email.mime.multipart import MIMEMultipart from email.mime.nonmultipart import MIMENonMultipart -from email import utils -from email import errors +from email.mime.text import MIMEText +from email.parser import Parser, HeaderParser +from email import base64mime from email import encoders +from email import errors from email import iterators -from email import base64mime from email import quoprimime +from email import utils from test.support import threading_helper from test.support.os_helper import unlink @@ -5508,7 +5509,12 @@ def test_long_headers_flatten(self): result = fp.getvalue() self._signed_parts_eq(original, result) - +class TestHeaderRegistry(TestEmailBase): + # See issue gh-93010. + def test_HeaderRegistry(self): + reg = HeaderRegistry() + a = reg('Content-Disposition', 'attachment; 0*00="foo"') + self.assertIsInstance(a.defects[0], errors.InvalidHeaderDefect) if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2022-05-20-15-52-43.gh-issue-93010.WF-cAc.rst b/Misc/NEWS.d/next/Library/2022-05-20-15-52-43.gh-issue-93010.WF-cAc.rst new file mode 100644 index 00000000000000..24208b5160ed52 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-05-20-15-52-43.gh-issue-93010.WF-cAc.rst @@ -0,0 +1 @@ +In a very special case, the email package tried to append the nonexistent ``InvalidHeaderError`` to the defect list. It should have been ``InvalidHeaderDefect``. From 251104f12d0cebb997f26f8ca3dac48202c7456a Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 23 May 2022 12:45:44 -0700 Subject: [PATCH 212/237] [3.10] gh-92859: Doc: add info about logging.debug() calling basicConfig() (GH-93063) (GH-93150) --- Doc/howto/logging.rst | 9 +++++---- Doc/library/logging.rst | 8 ++++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Doc/howto/logging.rst b/Doc/howto/logging.rst index fcc6bec7688002..ff4e1d73a96531 100644 --- a/Doc/howto/logging.rst +++ b/Doc/howto/logging.rst @@ -178,10 +178,11 @@ following example:: raise ValueError('Invalid log level: %s' % loglevel) logging.basicConfig(level=numeric_level, ...) -The call to :func:`basicConfig` should come *before* any calls to :func:`debug`, -:func:`info` etc. As it's intended as a one-off simple configuration facility, -only the first call will actually do anything: subsequent calls are effectively -no-ops. +The call to :func:`basicConfig` should come *before* any calls to +:func:`debug`, :func:`info`, etc. Otherwise, those functions will call +:func:`basicConfig` for you with the default options. As it's intended as a +one-off simple configuration facility, only the first call will actually do +anything: subsequent calls are effectively no-ops. If you run the above script several times, the messages from successive runs are appended to the file *example.log*. If you want each run to start afresh, diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index b32af94e85d012..c9b049388e6d9c 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -242,6 +242,10 @@ is the module's name in the Python package namespace. above example). In such circumstances, it is likely that specialized :class:`Formatter`\ s would be used with particular :class:`Handler`\ s. + If no handler is attached to this logger (or any of its ancestors, + taking into account the relevant :attr:`Logger.propagate` attributes), + the message will be sent to the handler set on :attr:`lastResort`. + .. versionchanged:: 3.2 The *stack_info* parameter was added. @@ -1038,6 +1042,10 @@ functions. above example). In such circumstances, it is likely that specialized :class:`Formatter`\ s would be used with particular :class:`Handler`\ s. + This function (as well as :func:`info`, :func:`warning`, :func:`error` and + :func:`critical`) will call :func:`basicConfig` if the root logger doesn't + have any handler attached. + .. versionchanged:: 3.2 The *stack_info* parameter was added. From c1b12495f67be5eca2692532de14e81a93025e6a Mon Sep 17 00:00:00 2001 From: Dennis Sweeney <36520290+sweeneyde@users.noreply.github.com> Date: Mon, 23 May 2022 19:53:38 -0400 Subject: [PATCH 213/237] gh-93061: Mark as artificial: backwards jump after async for (GH-93120) --- Lib/test/test_sys_settrace.py | 52 +++++++++++++++++++ ...2-05-22-02-37-50.gh-issue-93061.r70Imp.rst | 1 + Python/compile.c | 2 + 3 files changed, 55 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-05-22-02-37-50.gh-issue-93061.r70Imp.rst diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index 76d1aeecf69e45..4b3d096f163159 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -607,6 +607,58 @@ def run(tracer): self.compare_events(doit_async.__code__.co_firstlineno, tracer.events, events) + def test_async_for_backwards_jump_has_no_line(self): + async def arange(n): + for i in range(n): + yield i + async def f(): + async for i in arange(3): + if i > 100: + break # should never be traced + + tracer = self.make_tracer() + coro = f() + try: + sys.settrace(tracer.trace) + coro.send(None) + except Exception: + pass + finally: + sys.settrace(None) + + events = [ + (0, 'call'), + (1, 'line'), + (-3, 'call'), + (-2, 'line'), + (-1, 'line'), + (-1, 'return'), + (1, 'exception'), + (2, 'line'), + (1, 'line'), + (-1, 'call'), + (-2, 'line'), + (-1, 'line'), + (-1, 'return'), + (1, 'exception'), + (2, 'line'), + (1, 'line'), + (-1, 'call'), + (-2, 'line'), + (-1, 'line'), + (-1, 'return'), + (1, 'exception'), + (2, 'line'), + (1, 'line'), + (-1, 'call'), + (-2, 'line'), + (-2, 'return'), + (1, 'exception'), + (1, 'return'), + ] + self.compare_events(f.__code__.co_firstlineno, + tracer.events, events) + def test_21_repeated_pass(self): def func(): pass diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-05-22-02-37-50.gh-issue-93061.r70Imp.rst b/Misc/NEWS.d/next/Core and Builtins/2022-05-22-02-37-50.gh-issue-93061.r70Imp.rst new file mode 100644 index 00000000000000..d41e59028ad570 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-05-22-02-37-50.gh-issue-93061.r70Imp.rst @@ -0,0 +1 @@ +Backward jumps after ``async for`` loops are no longer given dubious line numbers. diff --git a/Python/compile.c b/Python/compile.c index f012406c066938..7210d42fc76992 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2925,6 +2925,8 @@ compiler_async_for(struct compiler *c, stmt_ty s) /* Success block for __anext__ */ VISIT(c, expr, s->v.AsyncFor.target); VISIT_SEQ(c, stmt, s->v.AsyncFor.body); + /* Mark jump as artificial */ + c->u->u_lineno = -1; ADDOP_JUMP(c, JUMP_ABSOLUTE, start); compiler_pop_fblock(c, FOR_LOOP, start); From a4bea26ee4da780b399eab8f9f7eaa1517f52d56 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 24 May 2022 01:52:29 -0700 Subject: [PATCH 214/237] gh-93065: Fix HAMT to iterate correctly over 7-level deep trees (GH-93066) (GH-93146) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also while there, clarify a few things about why we reduce the hash to 32 bits. Co-authored-by: Eli Libman Co-authored-by: Yury Selivanov Co-authored-by: Łukasz Langa (cherry picked from commit c1f5c903a7e4ed27190488f4e33b00d3c3d952e5) --- Include/internal/pycore_hamt.h | 14 +++++++- Lib/test/test_context.py | 35 +++++++++++++++++++ Misc/ACKS | 1 + ...2-05-21-23-21-37.gh-issue-93065.5I18WC.rst | 5 +++ Python/hamt.c | 14 ++++++-- 5 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-05-21-23-21-37.gh-issue-93065.5I18WC.rst diff --git a/Include/internal/pycore_hamt.h b/Include/internal/pycore_hamt.h index aaf655909551af..357d96616272a7 100644 --- a/Include/internal/pycore_hamt.h +++ b/Include/internal/pycore_hamt.h @@ -5,7 +5,19 @@ # error "this header requires Py_BUILD_CORE define" #endif -#define _Py_HAMT_MAX_TREE_DEPTH 7 + +/* +HAMT tree is shaped by hashes of keys. Every group of 5 bits of a hash denotes +the exact position of the key in one level of the tree. Since we're using +32 bit hashes, we can have at most 7 such levels. Although if there are +two distinct keys with equal hashes, they will have to occupy the same +cell in the 7th level of the tree -- so we'd put them in a "collision" node. +Which brings the total possible tree depth to 8. Read more about the actual +layout of the HAMT tree in `hamt.c`. + +This constant is used to define a datastucture for storing iteration state. +*/ +#define _Py_HAMT_MAX_TREE_DEPTH 8 #define PyHamt_Check(o) Py_IS_TYPE(o, &_PyHamt_Type) diff --git a/Lib/test/test_context.py b/Lib/test/test_context.py index 2d8b63a1f59581..689e3d4dc4591a 100644 --- a/Lib/test/test_context.py +++ b/Lib/test/test_context.py @@ -533,6 +533,41 @@ def test_hamt_collision_1(self): self.assertEqual(len(h4), 2) self.assertEqual(len(h5), 3) + def test_hamt_collision_3(self): + # Test that iteration works with the deepest tree possible. + # https://github.com/python/cpython/issues/93065 + + C = HashKey(0b10000000_00000000_00000000_00000000, 'C') + D = HashKey(0b10000000_00000000_00000000_00000000, 'D') + + E = HashKey(0b00000000_00000000_00000000_00000000, 'E') + + h = hamt() + h = h.set(C, 'C') + h = h.set(D, 'D') + h = h.set(E, 'E') + + # BitmapNode(size=2 count=1 bitmap=0b1): + # NULL: + # BitmapNode(size=2 count=1 bitmap=0b1): + # NULL: + # BitmapNode(size=2 count=1 bitmap=0b1): + # NULL: + # BitmapNode(size=2 count=1 bitmap=0b1): + # NULL: + # BitmapNode(size=2 count=1 bitmap=0b1): + # NULL: + # BitmapNode(size=2 count=1 bitmap=0b1): + # NULL: + # BitmapNode(size=4 count=2 bitmap=0b101): + # : 'E' + # NULL: + # CollisionNode(size=4 id=0x107a24520): + # : 'C' + # : 'D' + + self.assertEqual({k.name for k in h.keys()}, {'C', 'D', 'E'}) + def test_hamt_stress(self): COLLECTION_SIZE = 7000 TEST_ITERS_EVERY = 647 diff --git a/Misc/ACKS b/Misc/ACKS index b83f99956de0b1..7a363b99836a21 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1054,6 +1054,7 @@ Robert Li Xuanji Li Zekun Li Zheao Li +Eli Libman Dan Lidral-Porter Robert van Liere Ross Light diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-05-21-23-21-37.gh-issue-93065.5I18WC.rst b/Misc/NEWS.d/next/Core and Builtins/2022-05-21-23-21-37.gh-issue-93065.5I18WC.rst new file mode 100644 index 00000000000000..ea801653f75025 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-05-21-23-21-37.gh-issue-93065.5I18WC.rst @@ -0,0 +1,5 @@ +Fix contextvars HAMT implementation to handle iteration over deep trees. + +The bug was discovered and fixed by Eli Libman. See +`MagicStack/immutables#84 `_ +for more details. diff --git a/Python/hamt.c b/Python/hamt.c index e272e8808fd956..6572a554311cc0 100644 --- a/Python/hamt.c +++ b/Python/hamt.c @@ -408,14 +408,22 @@ hamt_hash(PyObject *o) return -1; } - /* While it's suboptimal to reduce Python's 64 bit hash to + /* While it's somewhat suboptimal to reduce Python's 64 bit hash to 32 bits via XOR, it seems that the resulting hash function is good enough (this is also how Long type is hashed in Java.) Storing 10, 100, 1000 Python strings results in a relatively shallow and uniform tree structure. - Please don't change this hashing algorithm, as there are many - tests that test some exact tree shape to cover all code paths. + Also it's worth noting that it would be possible to adapt the tree + structure to 64 bit hashes, but that would increase memory pressure + and provide little to no performance benefits for collections with + fewer than billions of key/value pairs. + + Important: do not change this hash reducing function. There are many + tests that need an exact tree shape to cover all code paths and + we do that by specifying concrete values for test data's `__hash__`. + If this function is changed most of the regression tests would + become useless. */ int32_t xored = (int32_t)(hash & 0xffffffffl) ^ (int32_t)(hash >> 32); return xored == -1 ? -2 : xored; From db2b1e1830b74f5e15abc3bac3fd67e35ca39951 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 24 May 2022 05:32:19 -0700 Subject: [PATCH 215/237] GH-93112: Fix missing ResourceDenied import in test_urllib2net (GH-93113) The code was moved out of test.support in 311110abcd8ab648dbf1803e36a8ba5d93fa019b (GH-20812), thus making ResourceDenied undefined. (cherry picked from commit 37c9a351b15c3fc4fcdca5dcb9ce19e51d7d2dd7) Co-authored-by: Florian Bruhin --- Lib/test/test_urllib2net.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_urllib2net.py b/Lib/test/test_urllib2net.py index aa41811560c789..a7e7c9f0b91e26 100644 --- a/Lib/test/test_urllib2net.py +++ b/Lib/test/test_urllib2net.py @@ -3,6 +3,7 @@ from test import support from test.support import os_helper from test.support import socket_helper +from test.support import ResourceDenied from test.test_urllib2 import sanepathname2url import os From 502dba0cf38ebd657d444fd49b8d648fe86bbb7d Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 24 May 2022 07:25:50 -0700 Subject: [PATCH 216/237] GH-89369: test_contextlib_async finalizes event loop after each test (GH-93074) Use asyncio.run(). (cherry picked from commit d2ef66a10be1250b13c32fbf3c0f9a9d2d98b124) Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> --- Lib/test/test_contextlib_async.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_contextlib_async.py b/Lib/test/test_contextlib_async.py index d6a34e22ac4249..d44d36209c7035 100644 --- a/Lib/test/test_contextlib_async.py +++ b/Lib/test/test_contextlib_async.py @@ -14,15 +14,12 @@ def _async_test(func): @functools.wraps(func) def wrapper(*args, **kwargs): coro = func(*args, **kwargs) - loop = asyncio.new_event_loop() - asyncio.set_event_loop(loop) - try: - return loop.run_until_complete(coro) - finally: - loop.close() - asyncio.set_event_loop_policy(None) + asyncio.run(coro) return wrapper +def tearDownModule(): + asyncio.set_event_loop_policy(None) + class TestAbstractAsyncContextManager(unittest.TestCase): From 2d5d01f26ba7939e8a035b6fe7abcc8490c9f208 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 24 May 2022 17:42:06 -0700 Subject: [PATCH 217/237] test.pythoninfo no longer requires socket (GH-93191) test.pythoninfo no longer fails if "import socket" fails: the socket module is now optional. (cherry picked from commit 4a31ed8a32699973ae1f779022794fdab9fa08ee) Co-authored-by: Victor Stinner --- Lib/test/pythoninfo.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index 8c8011b550acdc..005eae549cb045 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -532,7 +532,10 @@ def format_attr(attr, value): def collect_socket(info_add): - import socket + try: + import socket + except ImportError: + return hostname = socket.gethostname() info_add('socket.hostname', hostname) From 132ea299361e08c77c2b02ff25cf31eb73d3642f Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 25 May 2022 00:57:56 -0700 Subject: [PATCH 218/237] [3.10] gh-83245: Raise BadZipFile instead of ValueError when reading a corrupt ZIP file (GH-32291) (GH-93140) Co-authored-by: Serhiy Storchaka (cherry picked from commit 202ed2506c84cd98e9e35621b5b2929ceb717864) Co-authored-by: Sam Ezeh Automerge-Triggered-By: GH:serhiy-storchaka --- Lib/test/test_zipfile.py | 11 +++++++++++ Lib/zipfile.py | 2 ++ .../Library/2022-04-03-19-40-09.bpo-39064.76PbIz.rst | 2 ++ 3 files changed, 15 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2022-04-03-19-40-09.bpo-39064.76PbIz.rst diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index 6e06ee6a600439..e557d569a119ce 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -1736,6 +1736,17 @@ def test_empty_file_raises_BadZipFile(self): fp.write("short file") self.assertRaises(zipfile.BadZipFile, zipfile.ZipFile, TESTFN) + def test_negative_central_directory_offset_raises_BadZipFile(self): + # Zip file containing an empty EOCD record + buffer = bytearray(b'PK\x05\x06' + b'\0'*18) + + # Set the size of the central directory bytes to become 1, + # causing the central directory offset to become negative + for dirsize in 1, 2**32-1: + buffer[12:16] = struct.pack(' Date: Wed, 25 May 2022 01:17:57 -0700 Subject: [PATCH 219/237] test_threaded_import: Fix unittest.main spelling (GH-93114) (cherry picked from commit 19710145b496b5e5341630d80be9c400aa792bd1) Co-authored-by: Florian Bruhin --- Lib/test/test_importlib/test_threaded_import.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_importlib/test_threaded_import.py b/Lib/test/test_importlib/test_threaded_import.py index 76b028eac97bf9..d37eb2914f2c71 100644 --- a/Lib/test/test_importlib/test_threaded_import.py +++ b/Lib/test/test_importlib/test_threaded_import.py @@ -270,4 +270,4 @@ def setUpModule(): if __name__ == "__main__": - unittets.main() + unittest.main() From 9369942054fe3fe389f4f4ff808d33c5d7945052 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 26 May 2022 00:16:32 +0200 Subject: [PATCH 220/237] [3.10] gh-91924: Fix __ltrace__ for non-UTF-8 stdout encoding (#93214) Fix __ltrace__ debug feature if the stdout encoding is not UTF-8. If the stdout encoding is not UTF-8, the first call to lltrace_resume_frame() indirectly sets lltrace to 0 when calling unicode_check_encoding_errors() which calls encodings.search_function(). Add test_lltrace.test_lltrace() test. --- Lib/test/test_lltrace.py | 71 ++++++++++++++++++- ...2-05-25-04-07-22.gh-issue-91924.-UyO4q.rst | 2 + Python/ceval.c | 2 + 3 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-05-25-04-07-22.gh-issue-91924.-UyO4q.rst diff --git a/Lib/test/test_lltrace.py b/Lib/test/test_lltrace.py index 06e33f4c4c2f38..b5b0c10d404be9 100644 --- a/Lib/test/test_lltrace.py +++ b/Lib/test/test_lltrace.py @@ -1,11 +1,16 @@ -import os +import opcode +import re +import sys import textwrap import unittest -from test.support import os_helper +from test.support import os_helper, verbose from test.support.script_helper import assert_python_ok +Py_DEBUG = hasattr(sys, 'gettotalrefcount') + +@unittest.skipUnless(Py_DEBUG, "lltrace requires Py_DEBUG") class TestLLTrace(unittest.TestCase): def test_lltrace_does_not_crash_on_subscript_operator(self): @@ -27,5 +32,67 @@ def test_lltrace_does_not_crash_on_subscript_operator(self): assert_python_ok(os_helper.TESTFN) + def run_code(self, code): + code = textwrap.dedent(code).strip() + with open(os_helper.TESTFN, 'w', encoding='utf-8') as fd: + self.addCleanup(os_helper.unlink, os_helper.TESTFN) + fd.write(code) + status, stdout, stderr = assert_python_ok(os_helper.TESTFN) + self.assertEqual(stderr, b"") + self.assertEqual(status, 0) + result = stdout.decode('utf-8') + if verbose: + print("\n\n--- code ---") + print(code) + print("\n--- stdout ---") + print(result) + print() + return result + + def check_op(self, op, stdout, present): + op = opcode.opmap[op] + regex = re.compile(f': {op}($|, )', re.MULTILINE) + if present: + self.assertTrue(regex.search(stdout), + f'": {op}" not found in: {stdout}') + else: + self.assertFalse(regex.search(stdout), + f'": {op}" found in: {stdout}') + + def check_op_in(self, op, stdout): + self.check_op(op, stdout, True) + + def check_op_not_in(self, op, stdout): + self.check_op(op, stdout, False) + + def test_lltrace(self): + stdout = self.run_code(""" + def dont_trace_1(): + a = "a" + a = 10 * a + def trace_me(): + for i in range(3): + +i + def dont_trace_2(): + x = 42 + y = -x + dont_trace_1() + __ltrace__ = 1 + trace_me() + del __ltrace__ + dont_trace_2() + """) + self.check_op_in("GET_ITER", stdout) + self.check_op_in("FOR_ITER", stdout) + self.check_op_in("UNARY_POSITIVE", stdout) + self.check_op_in("POP_TOP", stdout) + + # before: dont_trace_1() is not traced + self.check_op_not_in("BINARY_MULTIPLY", stdout) + + # after: dont_trace_2() is not traced + self.check_op_not_in("UNARY_NEGATIVE", stdout) + + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-05-25-04-07-22.gh-issue-91924.-UyO4q.rst b/Misc/NEWS.d/next/Core and Builtins/2022-05-25-04-07-22.gh-issue-91924.-UyO4q.rst new file mode 100644 index 00000000000000..3986ad8aa8d951 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-05-25-04-07-22.gh-issue-91924.-UyO4q.rst @@ -0,0 +1,2 @@ +Fix ``__ltrace__`` debug feature if the stdout encoding is not UTF-8. Patch +by Victor Stinner. diff --git a/Python/ceval.c b/Python/ceval.c index 21674e0be13240..9a193c994d12ec 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -5377,6 +5377,8 @@ prtrace(PyThreadState *tstate, PyObject *v, const char *str) } printf("\n"); PyErr_Restore(type, value, traceback); + // gh-91924: PyObject_Print() can indirectly set lltrace to 0 + lltrace = 1; return 1; } #endif From 9912b3d989b0cb442e9f9d55fbdd30d55591e2fc Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 27 May 2022 12:25:21 -0700 Subject: [PATCH 221/237] gh-77024: test.support: Improve documentation (GH-92513) This is a rework of GH-5774 on current main. I was a bit more conservative in making changes than the original PR. See @csabella's comments on issue GH-77024 and the discussion on GH-5774 for explanations of several of the changes. Co-authored-by: Cheryl Sabella Co-authored-by: Alex Waygood (cherry picked from commit 8995177030c8b41885ad92b260279b7e622ecaea) Co-authored-by: Jelle Zijlstra --- Doc/library/test.rst | 110 ++++++++++++++++++++++++++----------------- 1 file changed, 68 insertions(+), 42 deletions(-) diff --git a/Doc/library/test.rst b/Doc/library/test.rst index a8dc35476fc9bd..07c3339661ad5b 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -359,13 +359,19 @@ The :mod:`test.support` module defines the following constants: .. data:: MISSING_C_DOCSTRINGS - Return ``True`` if running on CPython, not on Windows, and configuration - not set with ``WITH_DOC_STRINGS``. + Set to ``True`` if Python is built without docstrings (the + :c:macro:`WITH_DOC_STRINGS` macro is not defined). + See the :option:`configure --without-doc-strings <--without-doc-strings>` option. + + See also the :data:`HAVE_DOCSTRINGS` variable. .. data:: HAVE_DOCSTRINGS - Check for presence of docstrings. + Set to ``True`` if function docstrings are available. + See the :option:`python -OO <-O>` option, which strips docstrings of functions implemented in Python. + + See also the :data:`MISSING_C_DOCSTRINGS` variable. .. data:: TEST_HTTP_URL @@ -423,11 +429,6 @@ The :mod:`test.support` module defines the following functions: Used when tests are executed by :mod:`test.regrtest`. -.. function:: system_must_validate_cert(f) - - Raise :exc:`unittest.SkipTest` on TLS certification validation failures. - - .. function:: sortdict(dict) Return a repr of *dict* with keys sorted. @@ -445,12 +446,12 @@ The :mod:`test.support` module defines the following functions: .. function:: match_test(test) - Match *test* to patterns set in :func:`set_match_tests`. + Determine whether *test* matches the patterns set in :func:`set_match_tests`. -.. function:: set_match_tests(patterns) +.. function:: set_match_tests(accept_patterns=None, ignore_patterns=None) - Define match test with regular expression *patterns*. + Define match patterns on test filenames and test method names for filtering tests. .. function:: run_unittest(*classes) @@ -490,7 +491,9 @@ The :mod:`test.support` module defines the following functions: .. function:: check_impl_detail(**guards) Use this check to guard CPython's implementation-specific tests or to - run them only on the implementations guarded by the arguments:: + run them only on the implementations guarded by the arguments. This + function returns ``True`` or ``False`` depending on the host platform. + Example usage:: check_impl_detail() # Only on CPython (default). check_impl_detail(jython=True) # Only on Jython. @@ -509,7 +512,7 @@ The :mod:`test.support` module defines the following functions: time the regrtest began. -.. function:: get_original_stdout +.. function:: get_original_stdout() Return the original stdout set by :func:`record_original_stdout` or ``sys.stdout`` if it's not set. @@ -554,7 +557,7 @@ The :mod:`test.support` module defines the following functions: .. function:: disable_faulthandler() - A context manager that replaces ``sys.stderr`` with ``sys.__stderr__``. + A context manager that temporary disables :mod:`faulthandler`. .. function:: gc_collect() @@ -567,8 +570,8 @@ The :mod:`test.support` module defines the following functions: .. function:: disable_gc() - A context manager that disables the garbage collector upon entry and - reenables it upon exit. + A context manager that disables the garbage collector on entry. On + exit, the garbage collector is restored to its prior state. .. function:: swap_attr(obj, attr, new_val) @@ -633,14 +636,14 @@ The :mod:`test.support` module defines the following functions: .. function:: calcobjsize(fmt) - Return :func:`struct.calcsize` for ``nP{fmt}0n`` or, if ``gettotalrefcount`` - exists, ``2PnP{fmt}0P``. + Return the size of the :c:type:`PyObject` whose structure members are + defined by *fmt*. The returned value includes the size of the Python object header and alignment. .. function:: calcvobjsize(fmt) - Return :func:`struct.calcsize` for ``nPn{fmt}0n`` or, if ``gettotalrefcount`` - exists, ``2PnPn{fmt}0P``. + Return the size of the :c:type:`PyVarObject` whose structure members are + defined by *fmt*. The returned value includes the size of the Python object header and alignment. .. function:: checksizeof(test, o, size) @@ -656,6 +659,11 @@ The :mod:`test.support` module defines the following functions: have an associated comment identifying the relevant tracker issue. +.. function:: system_must_validate_cert(f) + + A decorator that skips the decorated test on TLS certification validation failures. + + .. decorator:: run_with_locale(catstr, *locales) A decorator for running a function in a different locale, correctly @@ -673,19 +681,19 @@ The :mod:`test.support` module defines the following functions: .. decorator:: requires_freebsd_version(*min_version) Decorator for the minimum version when running test on FreeBSD. If the - FreeBSD version is less than the minimum, raise :exc:`unittest.SkipTest`. + FreeBSD version is less than the minimum, the test is skipped. .. decorator:: requires_linux_version(*min_version) Decorator for the minimum version when running test on Linux. If the - Linux version is less than the minimum, raise :exc:`unittest.SkipTest`. + Linux version is less than the minimum, the test is skipped. .. decorator:: requires_mac_version(*min_version) Decorator for the minimum version when running test on macOS. If the - macOS version is less than the minimum, raise :exc:`unittest.SkipTest`. + macOS version is less than the minimum, the test is skipped. .. decorator:: requires_IEEE_754 @@ -723,7 +731,7 @@ The :mod:`test.support` module defines the following functions: Decorator for only running the test if :data:`HAVE_DOCSTRINGS`. -.. decorator:: cpython_only(test) +.. decorator:: cpython_only Decorator for tests only applicable to CPython. @@ -734,12 +742,12 @@ The :mod:`test.support` module defines the following functions: returns ``False``, then uses *msg* as the reason for skipping the test. -.. decorator:: no_tracing(func) +.. decorator:: no_tracing Decorator to temporarily turn off tracing for the duration of the test. -.. decorator:: refcount_test(test) +.. decorator:: refcount_test Decorator for tests which involve reference counting. The decorator does not run the test if it is not run by CPython. Any trace function is unset @@ -762,10 +770,9 @@ The :mod:`test.support` module defines the following functions: means the test doesn't support dummy runs when ``-M`` is not specified. -.. decorator:: bigaddrspacetest(f) +.. decorator:: bigaddrspacetest - Decorator for tests that fill the address space. *f* is the function to - wrap. + Decorator for tests that fill the address space. .. function:: check_syntax_error(testcase, statement, errtext='', *, lineno=None, offset=None) @@ -867,7 +874,7 @@ The :mod:`test.support` module defines the following functions: .. function:: check_free_after_iterating(test, iter, cls, args=()) - Assert that *iter* is deallocated after iterating. + Assert instances of *cls* are deallocated after iterating. .. function:: missing_compiler_executable(cmd_names=[]) @@ -958,6 +965,16 @@ The :mod:`test.support` module defines the following classes: Class to save and restore signal handlers registered by the Python signal handler. + .. method:: save(self) + + Save the signal handlers to a dictionary mapping signal numbers to the + current signal handler. + + .. method:: restore(self) + + Set the signal numbers from the :meth:`save` dictionary to the saved + handler. + .. class:: Matcher() @@ -1101,11 +1118,11 @@ script execution tests. variables *env_vars* succeeds (``rc == 0``) and return a ``(return code, stdout, stderr)`` tuple. - If the ``__cleanenv`` keyword is set, *env_vars* is used as a fresh + If the *__cleanenv* keyword-only parameter is set, *env_vars* is used as a fresh environment. Python is started in isolated mode (command line option ``-I``), - except if the ``__isolated`` keyword is set to ``False``. + except if the *__isolated* keyword-only parameter is set to ``False``. .. versionchanged:: 3.9 The function no longer strips whitespaces from *stderr*. @@ -1216,15 +1233,17 @@ The :mod:`test.support.threading_helper` module provides support for threading t is still alive after *timeout* seconds. -.. decorator:: reap_threads(func) +.. decorator:: reap_threads Decorator to ensure the threads are cleaned up even if the test fails. .. function:: start_threads(threads, unlock=None) - Context manager to start *threads*. It attempts to join the threads upon - exit. + Context manager to start *threads*, which is a sequence of threads. + *unlock* is a function called after the threads are started, even if an + exception was raised; an example would be :meth:`threading.Event.set`. + ``start_threads`` will attempt to join the started threads upon exit. .. function:: threading_cleanup(*original_values) @@ -1306,7 +1325,10 @@ The :mod:`test.support.os_helper` module provides support for os tests. .. data:: TESTFN_NONASCII - Set to a filename containing the :data:`FS_NONASCII` character. + Set to a filename containing the :data:`FS_NONASCII` character, if it exists. + This guarantees that if the filename exists, it can be encoded and decoded + with the default filesystem encoding. This allows tests that require a + non-ASCII filename to be easily skipped on platforms where they can't work. .. data:: TESTFN_UNENCODABLE @@ -1404,13 +1426,16 @@ The :mod:`test.support.os_helper` module provides support for os tests. .. function:: rmdir(filename) Call :func:`os.rmdir` on *filename*. On Windows platforms, this is - wrapped with a wait loop that checks for the existence of the file. + wrapped with a wait loop that checks for the existence of the file, + which is needed due to antivirus programs that can hold files open and prevent + deletion. .. function:: rmtree(path) Call :func:`shutil.rmtree` on *path* or call :func:`os.lstat` and - :func:`os.rmdir` to remove a path and its contents. On Windows platforms, + :func:`os.rmdir` to remove a path and its contents. As with :func:`rmdir`, + on Windows platforms this is wrapped with a wait loop that checks for the existence of the files. @@ -1457,7 +1482,8 @@ The :mod:`test.support.os_helper` module provides support for os tests. .. function:: unlink(filename) - Call :func:`os.unlink` on *filename*. On Windows platforms, this is + Call :func:`os.unlink` on *filename*. As with :func:`rmdir`, + on Windows platforms, this is wrapped with a wait loop that checks for the existence of the file. @@ -1514,7 +1540,7 @@ The :mod:`test.support.import_helper` module provides support for import tests. .. versionadded:: 3.1 -.. function:: import_module(name, deprecated=False, *, required_on()) +.. function:: import_module(name, deprecated=False, *, required_on=()) This function imports and returns the named module. Unlike a normal import, this function raises :exc:`unittest.SkipTest` if the module @@ -1556,7 +1582,7 @@ The :mod:`test.support.import_helper` module provides support for import tests. A context manager to force import to return a new module reference. This is useful for testing module-level behaviors, such as the emission of a - DeprecationWarning on import. Example usage:: + :exc:`DeprecationWarning` on import. Example usage:: with CleanImport('foo'): importlib.import_module('foo') # New reference. @@ -1564,7 +1590,7 @@ The :mod:`test.support.import_helper` module provides support for import tests. .. class:: DirsOnSysPath(*paths) - A context manager to temporarily add directories to sys.path. + A context manager to temporarily add directories to :data:`sys.path`. This makes a copy of :data:`sys.path`, appends any directories given as positional arguments, then reverts :data:`sys.path` to the copied From 550c44b89513ea96d209e2ff761302238715f082 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 28 May 2022 11:48:25 -0700 Subject: [PATCH 222/237] gh-92839: fixed typo in _bisectmodule.c (line 131) (GH-92849) (#93321) --- Lib/test/test_bisect.py | 6 ++++++ .../Library/2022-05-16-14-35-39.gh-issue-92839.owSMyo.rst | 1 + Modules/_bisectmodule.c | 4 ++-- 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-05-16-14-35-39.gh-issue-92839.owSMyo.rst diff --git a/Lib/test/test_bisect.py b/Lib/test/test_bisect.py index 20f8b9d7c0aa87..ba108221ebf454 100644 --- a/Lib/test/test_bisect.py +++ b/Lib/test/test_bisect.py @@ -257,6 +257,12 @@ def test_insort(self): target ) + def test_insort_keynotNone(self): + x = [] + y = {"a": 2, "b": 1} + for f in (self.module.insort_left, self.module.insort_right): + self.assertRaises(TypeError, f, x, y, key = "b") + class TestBisectPython(TestBisect, unittest.TestCase): module = py_bisect diff --git a/Misc/NEWS.d/next/Library/2022-05-16-14-35-39.gh-issue-92839.owSMyo.rst b/Misc/NEWS.d/next/Library/2022-05-16-14-35-39.gh-issue-92839.owSMyo.rst new file mode 100644 index 00000000000000..b425bd9c47bc91 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-05-16-14-35-39.gh-issue-92839.owSMyo.rst @@ -0,0 +1 @@ +Fixed crash resulting from calling bisect.insort() or bisect.insort_left() with the key argument not equal to None. diff --git a/Modules/_bisectmodule.c b/Modules/_bisectmodule.c index 26c4b9bfb26b22..16f981e7296ba9 100644 --- a/Modules/_bisectmodule.c +++ b/Modules/_bisectmodule.c @@ -118,7 +118,7 @@ _bisect_insort_right_impl(PyObject *module, PyObject *a, PyObject *x, index = internal_bisect_right(a, x, lo, hi, key); } else { key_x = PyObject_CallOneArg(key, x); - if (x == NULL) { + if (key_x == NULL) { return NULL; } index = internal_bisect_right(a, key_x, lo, hi, key); @@ -245,7 +245,7 @@ _bisect_insort_left_impl(PyObject *module, PyObject *a, PyObject *x, index = internal_bisect_left(a, x, lo, hi, key); } else { key_x = PyObject_CallOneArg(key, x); - if (x == NULL) { + if (key_x == NULL) { return NULL; } index = internal_bisect_left(a, key_x, lo, hi, key); From 738c730b5cde0c07151dcca375d8983a7e4d5b7d Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 28 May 2022 20:41:40 -0700 Subject: [PATCH 223/237] gh-92240 : Include release dates for "What's New In Python 3.X" (GH-92937) Co-authored-by: Jelle Zijlstra Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> (cherry picked from commit 877ad7b3b2778a305d3989d58ebd68cb01baf26e) Co-authored-by: georgically <40323509+georgically@users.noreply.github.com> --- Doc/whatsnew/2.5.rst | 2 +- Doc/whatsnew/2.6.rst | 2 +- Doc/whatsnew/3.0.rst | 6 +++--- Doc/whatsnew/3.1.rst | 1 + Doc/whatsnew/3.10.rst | 2 +- Doc/whatsnew/3.2.rst | 3 ++- Doc/whatsnew/3.8.rst | 1 + Doc/whatsnew/3.9.rst | 2 +- .../2022-05-18-23-58-26.gh-issue-92240.bHvYiz.rst | 2 ++ 9 files changed, 13 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2022-05-18-23-58-26.gh-issue-92240.bHvYiz.rst diff --git a/Doc/whatsnew/2.5.rst b/Doc/whatsnew/2.5.rst index 5816380e102f99..103a72f913c631 100644 --- a/Doc/whatsnew/2.5.rst +++ b/Doc/whatsnew/2.5.rst @@ -11,7 +11,7 @@ This article explains the new features in Python 2.5. The final release of Python 2.5 is scheduled for August 2006; :pep:`356` describes the planned -release schedule. +release schedule. Python 2.5 was released on September 19, 2006. The changes in Python 2.5 are an interesting mix of language and library improvements. The library enhancements will be more important to Python's user diff --git a/Doc/whatsnew/2.6.rst b/Doc/whatsnew/2.6.rst index b6174a19a178b6..08a7c58b0f0805 100644 --- a/Doc/whatsnew/2.6.rst +++ b/Doc/whatsnew/2.6.rst @@ -49,7 +49,7 @@ This saves the maintainer some effort going through the SVN logs when researching a change. -This article explains the new features in Python 2.6, released on October 1 +This article explains the new features in Python 2.6, released on October 1, 2008. The release schedule is described in :pep:`361`. The major theme of Python 2.6 is preparing the migration path to diff --git a/Doc/whatsnew/3.0.rst b/Doc/whatsnew/3.0.rst index 880958d3edb900..4da3507ad2e892 100644 --- a/Doc/whatsnew/3.0.rst +++ b/Doc/whatsnew/3.0.rst @@ -53,9 +53,9 @@ This article explains the new features in Python 3.0, compared to 2.6. Python 3.0, also known as "Python 3000" or "Py3K", is the first ever -*intentionally backwards incompatible* Python release. There are more -changes than in a typical release, and more that are important for all -Python users. Nevertheless, after digesting the changes, you'll find +*intentionally backwards incompatible* Python release. Python 3.0 was released on December 3, 2008. +There are more changes than in a typical release, and more that are important for all +Python users. Nevertheless, after digesting the changes, you'll find that Python really hasn't changed all that much -- by and large, we're mostly fixing well-known annoyances and warts, and removing a lot of old cruft. diff --git a/Doc/whatsnew/3.1.rst b/Doc/whatsnew/3.1.rst index f1e6d0c4f3dd68..3d89b97fa8f1b8 100644 --- a/Doc/whatsnew/3.1.rst +++ b/Doc/whatsnew/3.1.rst @@ -47,6 +47,7 @@ when researching a change. This article explains the new features in Python 3.1, compared to 3.0. +Python 3.1 was released on June 27, 2009. PEP 372: Ordered Dictionaries diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 55e7d62b541597..212444a25836b8 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -47,7 +47,7 @@ when researching a change. This article explains the new features in Python 3.10, compared to 3.9. - +Python 3.10 was released on October 4, 2021. For full details, see the :ref:`changelog `. Summary -- Release highlights diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst index ec01a70f8ae0af..15f8672adda0d7 100644 --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -48,7 +48,8 @@ This saves the maintainer the effort of going through the SVN log when researching a change. -This article explains the new features in Python 3.2 as compared to 3.1. It +This article explains the new features in Python 3.2 as compared to 3.1. +Python 3.2 was released on February 20, 2011. It focuses on a few highlights and gives a few examples. For full details, see the `Misc/NEWS `_ diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 94d3b3f15fd29e..163332401deeb3 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -45,6 +45,7 @@ :Editor: Raymond Hettinger This article explains the new features in Python 3.8, compared to 3.7. +Python 3.8 was released on October 14, 2019. For full details, see the :ref:`changelog `. .. testsetup:: diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index e2455bce7d368e..9408e3609e8c7f 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -45,7 +45,7 @@ when researching a change. This article explains the new features in Python 3.9, compared to 3.8. -Python 3.9 was released on October 5th, 2020. +Python 3.9 was released on October 5, 2020. For full details, see the :ref:`changelog `. diff --git a/Misc/NEWS.d/next/Documentation/2022-05-18-23-58-26.gh-issue-92240.bHvYiz.rst b/Misc/NEWS.d/next/Documentation/2022-05-18-23-58-26.gh-issue-92240.bHvYiz.rst new file mode 100644 index 00000000000000..53b2a66c9779c2 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-05-18-23-58-26.gh-issue-92240.bHvYiz.rst @@ -0,0 +1,2 @@ +Added release dates for +"What's New in Python 3.X" for 3.0, 3.1, 3.2, 3.8 and 3.10 From 561c709af327359979f43388461f9f937666d192 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 29 May 2022 01:22:35 -0700 Subject: [PATCH 224/237] test.pythoninfo logs more build info (GH-93225) (#93256) Log also test.support.check_sanitizer() values. (cherry picked from commit 06dd26f89f35b6d6ef4b68c169cb6c675af7e4a4) Co-authored-by: Victor Stinner Co-authored-by: Victor Stinner Co-authored-by: Jelle Zijlstra --- Lib/test/pythoninfo.py | 50 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index 005eae549cb045..479e60b16b691b 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -9,6 +9,9 @@ import warnings +MS_WINDOWS = (sys.platform == 'win32') + + def normalize_text(text): if text is None: return None @@ -125,13 +128,21 @@ def collect_sys(info_add): encoding = '%s/%s' % (encoding, errors) info_add('sys.%s.encoding' % name, encoding) - # Were we compiled --with-pydebug or with #define Py_DEBUG? + # Were we compiled --with-pydebug? Py_DEBUG = hasattr(sys, 'gettotalrefcount') if Py_DEBUG: text = 'Yes (sys.gettotalrefcount() present)' else: text = 'No (sys.gettotalrefcount() missing)' - info_add('Py_DEBUG', text) + info_add('build.Py_DEBUG', text) + + # Were we compiled --with-trace-refs? + Py_TRACE_REFS = hasattr(sys, 'getobjects') + if Py_TRACE_REFS: + text = 'Yes (sys.getobjects() present)' + else: + text = 'No (sys.getobjects() missing)' + info_add('build.Py_REF_DEBUG', text) def collect_platform(info_add): @@ -444,6 +455,11 @@ def collect_datetime(info_add): def collect_sysconfig(info_add): + # On Windows, sysconfig is not reliable to get macros used + # to build Python + if MS_WINDOWS: + return + import sysconfig for name in ( @@ -477,6 +493,28 @@ def collect_sysconfig(info_add): value = normalize_text(value) info_add('sysconfig[%s]' % name, value) + PY_CFLAGS = sysconfig.get_config_var('PY_CFLAGS') + NDEBUG = (PY_CFLAGS and '-DNDEBUG' in PY_CFLAGS) + if NDEBUG: + text = 'ignore assertions (macro defined)' + else: + text= 'build assertions (macro not defined)' + info_add('build.NDEBUG',text) + + for name in ( + 'WITH_DOC_STRINGS', + 'WITH_DTRACE', + 'WITH_FREELISTS', + 'WITH_PYMALLOC', + 'WITH_VALGRIND', + ): + value = sysconfig.get_config_var(name) + if value: + text = 'Yes' + else: + text = 'No' + info_add(f'build.{name}', text) + def collect_ssl(info_add): import os @@ -588,7 +626,6 @@ def collect_testcapi(info_add): return call_func(info_add, 'pymem.allocator', _testcapi, 'pymem_getallocatorsname') - copy_attr(info_add, 'pymem.with_pymalloc', _testcapi, 'WITH_PYMALLOC') def collect_resource(info_add): @@ -630,6 +667,13 @@ def collect_test_support(info_add): call_func(info_add, 'test_support._is_gui_available', support, '_is_gui_available') call_func(info_add, 'test_support.python_is_optimized', support, 'python_is_optimized') + info_add('test_support.check_sanitizer(address=True)', + support.check_sanitizer(address=True)) + info_add('test_support.check_sanitizer(memory=True)', + support.check_sanitizer(memory=True)) + info_add('test_support.check_sanitizer(ub=True)', + support.check_sanitizer(ub=True)) + def collect_cc(info_add): import subprocess From c649526f923c70d9db201b08d8a850831b5cf989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric?= Date: Sun, 29 May 2022 14:04:23 -0400 Subject: [PATCH 225/237] [3.10] gh-93217: fix some issues in man page and --help (GH-93219) (#93261) --- Misc/python.man | 10 +++++++--- Python/initconfig.c | 7 +++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Misc/python.man b/Misc/python.man index 45a49271d4dfe3..6b21fdc8790bce 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -66,10 +66,10 @@ python \- an interpreted, interactive, object-oriented programming language .B \-x ] [ -[ .B \-X .I option ] +[ .B \-? ] .br @@ -302,7 +302,8 @@ Set implementation specific option. The following options are available: more verbose than the default if the code is correct: new warnings are only emitted when an issue is detected. Effect of the developer mode: * Add default warning filter, as -W default - * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function + * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() + C function * Enable the faulthandler module to dump the Python traceback on a crash * Enable asyncio debug mode * Set the dev_mode attribute of sys.flags to True @@ -313,7 +314,10 @@ Set implementation specific option. The following options are available: otherwise activate automatically). See PYTHONUTF8 for more details -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the - given directory instead of to the code tree. + given directory instead of to the code tree. + + -X warn_default_encoding: enable opt-in EncodingWarning for 'encoding=None' + .TP .B \-x Skip the first line of the source. This is intended for a DOS diff --git a/Python/initconfig.c b/Python/initconfig.c index b2986116fdc350..0341e7baa210c9 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -41,7 +41,7 @@ Options and arguments (and corresponding environment variables):\n\ -d : turn on parser debugging output (for experts only, only works on\n\ debug builds); also PYTHONDEBUG=x\n\ -E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\ --h : print this help message and exit (also --help)\n\ +-h : print this help message and exit (also -? or --help)\n\ "; static const char usage_2[] = "\ -i : inspect interactively after running script; forces a prompt even\n\ @@ -67,7 +67,6 @@ static const char usage_3[] = "\ also PYTHONWARNINGS=arg\n\ -x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\ -X opt : set implementation-specific option. The following options are available:\n\ -\n\ -X faulthandler: enable faulthandler\n\ -X showrefcount: output the total reference count and number of used\n\ memory blocks when the program finishes or after each statement in the\n\ @@ -84,7 +83,8 @@ static const char usage_3[] = "\ checks which are too expensive to be enabled by default. Effect of the\n\ developer mode:\n\ * Add default warning filter, as -W default\n\ - * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function\n\ + * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks()\n\ + C function\n\ * Enable the faulthandler module to dump the Python traceback on a crash\n\ * Enable asyncio debug mode\n\ * Set the dev_mode attribute of sys.flags to True\n\ @@ -95,7 +95,6 @@ static const char usage_3[] = "\ -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\ given directory instead of to the code tree\n\ -X warn_default_encoding: enable opt-in EncodingWarning for 'encoding=None'\n\ -\n\ --check-hash-based-pycs always|default|never:\n\ control how Python invalidates hash-based .pyc files\n\ "; From aa06a8409927b43dee5cfe4a49d6190e7bddebad Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 29 May 2022 19:03:15 -0700 Subject: [PATCH 226/237] bpo-42272: fix misleading warning filter message/module docs (GH-23172) * bpo-42272: improve message/module warning filter docs "The Warnings Filter" section of the warnings module documentation describes the message and module filters as "a string containing a regular expression". While that is true when they are arguments to the filterwarnings function, it is not true when they appear in -W or $PYTHONWARNINGS where they are matched literally (after stripping any starting/ending whitespace). Update the documentation to note when they are matched literally. Also clarify that module matches the "fully-qualified module name", rather than "module name" which is ambiguous. skip news (since this is a doc fix) Signed-off-by: Kevin Locke * bpo-42272: remove bad submodule warning filter doc The `error:::mymodule[.*]` example in the "Describing Warning Filters" section of the warnings module documentation does not behave as the comment describes. Since the module portion of the filter string is interpreted literally, it would match a module with a fully-qualified name that is literally `mymodule[.*]`. Unfortunately, there is not a way to match '"module" and any subpackages of "mymodule"' as documented, since the module part of a filter string is matched literally. Instead, update the filter and comment to match only "mymodule". skip news (since this is a doc fix) Signed-off-by: Kevin Locke * bpo-42272: add warning filter doc changes to NEWS Signed-off-by: Kevin Locke (cherry picked from commit 8136606769661c103c46d142e52ecbbbb88803f6) Co-authored-by: Kevin Locke --- Doc/library/warnings.rst | 16 ++++++++++------ ...2022-05-26-11-33-23.gh-issue-86438.kEGGmK.rst | 3 +++ 2 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2022-05-26-11-33-23.gh-issue-86438.kEGGmK.rst diff --git a/Doc/library/warnings.rst b/Doc/library/warnings.rst index 289b28229e1a00..8f2a5accd472be 100644 --- a/Doc/library/warnings.rst +++ b/Doc/library/warnings.rst @@ -154,14 +154,19 @@ the disposition of the match. Each entry is a tuple of the form (*action*, +---------------+----------------------------------------------+ * *message* is a string containing a regular expression that the start of - the warning message must match. The expression is compiled to always be - case-insensitive. + the warning message must match, case-insensitively. In :option:`-W` and + :envvar:`PYTHONWARNINGS`, *message* is a literal string that the start of the + warning message must contain (case-insensitively), ignoring any whitespace at + the start or end of *message*. * *category* is a class (a subclass of :exc:`Warning`) of which the warning category must be a subclass in order to match. -* *module* is a string containing a regular expression that the module name must - match. The expression is compiled to be case-sensitive. +* *module* is a string containing a regular expression that the start of the + fully-qualified module name must match, case-sensitively. In :option:`-W` and + :envvar:`PYTHONWARNINGS`, *module* is a literal string that the + fully-qualified module name must be equal to (case-sensitively), ignoring any + whitespace at the start or end of *module*. * *lineno* is an integer that the line number where the warning occurred must match, or ``0`` to match all line numbers. @@ -207,8 +212,7 @@ Some examples:: error::ResourceWarning # Treat ResourceWarning messages as errors default::DeprecationWarning # Show DeprecationWarning messages ignore,default:::mymodule # Only report warnings triggered by "mymodule" - error:::mymodule[.*] # Convert warnings to errors in "mymodule" - # and any subpackages of "mymodule" + error:::mymodule # Convert warnings to errors in "mymodule" .. _default-warning-filter: diff --git a/Misc/NEWS.d/next/Documentation/2022-05-26-11-33-23.gh-issue-86438.kEGGmK.rst b/Misc/NEWS.d/next/Documentation/2022-05-26-11-33-23.gh-issue-86438.kEGGmK.rst new file mode 100644 index 00000000000000..75abfdd63b8b2e --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-05-26-11-33-23.gh-issue-86438.kEGGmK.rst @@ -0,0 +1,3 @@ +Clarify that :option:`-W` and :envvar:`PYTHONWARNINGS` are matched literally +and case-insensitively, rather than as regular expressions, in +:mod:`warnings`. From 372afb7a9b1fff2fcc724f999744b6126f0f6e07 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 29 May 2022 20:03:11 -0700 Subject: [PATCH 227/237] Fix typo in Lib/idlelib/idle_test/test_parenmatch.py (GH-93332) (#93340) Co-authored-by: Terry Jan Reedy (cherry picked from commit 4f195f9db168bfe3360607eb45ba8d9ac98506ec) Co-authored-by: luzpaz --- Lib/idlelib/idle_test/test_parenmatch.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/idlelib/idle_test/test_parenmatch.py b/Lib/idlelib/idle_test/test_parenmatch.py index 4a41d8433d5483..2e10d7cd36760f 100644 --- a/Lib/idlelib/idle_test/test_parenmatch.py +++ b/Lib/idlelib/idle_test/test_parenmatch.py @@ -83,12 +83,12 @@ def test_paren_corner(self): """ Test corner cases in flash_paren_event and paren_closed_event. - These cases force conditional expression and alternate paths. + Force execution of conditional expressions and alternate paths. """ text = self.text pm = self.get_parenmatch() - text.insert('insert', '# this is a commen)') + text.insert('insert', '# Comment.)') pm.paren_closed_event('event') text.insert('insert', '\ndef') From 694455d5eddaee6b8a0a1e47fc0de56c02a489fe Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 31 May 2022 10:49:14 -0700 Subject: [PATCH 228/237] Remove VOC reference (93333) VOC has been archived by the BeeWare project, and they are instead embedding CPython, rather than transpiling to Java bytecode. (cherry picked from commit bb900712a5511ba82ef64105fe28d2a6886a8fed) Co-authored-by: Carl Bordum Hansen --- Doc/faq/design.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst index ff83a1b8134b77..a624fdb07a17df 100644 --- a/Doc/faq/design.rst +++ b/Doc/faq/design.rst @@ -324,8 +324,7 @@ Can Python be compiled to machine code, C or some other language? `Cython `_ compiles a modified version of Python with optional annotations into C extensions. `Nuitka `_ is an up-and-coming compiler of Python into C++ code, aiming to support the full -Python language. For compiling to Java you can consider -`VOC `_. +Python language. How does Python manage memory? From 0b7aae88d0e71304bf6d78c0c0192a1d3e0a5fe0 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 1 Jun 2022 00:31:31 -0700 Subject: [PATCH 229/237] Remove the execution bit to some socket-related files. (GH-93368) (cherry picked from commit 5247389369ac3da35c44f7c0d8f4facc0300883a) Co-authored-by: Ezio Melotti --- Doc/library/socket.rst | 0 Lib/socket.py | 0 Lib/test/test_socket.py | 0 3 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 Doc/library/socket.rst mode change 100755 => 100644 Lib/socket.py mode change 100755 => 100644 Lib/test/test_socket.py diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst old mode 100755 new mode 100644 diff --git a/Lib/socket.py b/Lib/socket.py old mode 100755 new mode 100644 diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py old mode 100755 new mode 100644 From 855be47a02e68bf9217ef8ab79dbd94ddc3298f1 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 1 Jun 2022 18:04:43 -0700 Subject: [PATCH 230/237] gh-93418: Fix an assert when an f-string expression is followed by an '=', but no closing brace. (gh-93419) (gh-93423) (cherry picked from commit ee70c70aa93d7a41cbe47a0b361b17f9d7ec8acd) Co-authored-by: Eric V. Smith Co-authored-by: Eric V. Smith --- Lib/test/test_fstring.py | 1 + .../2022-06-01-17-47-40.gh-issue-93418.24dJuc.rst | 2 ++ Parser/string_parser.c | 4 +++- 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-06-01-17-47-40.gh-issue-93418.24dJuc.rst diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index 0c255c2af22179..8f3b609d33bc97 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -1055,6 +1055,7 @@ def test_mismatched_braces(self): "f'{'", "f'x{<'", # See bpo-46762. "f'x{>'", + "f'{i='", # See gh-93418. ]) # But these are just normal strings. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-06-01-17-47-40.gh-issue-93418.24dJuc.rst b/Misc/NEWS.d/next/Core and Builtins/2022-06-01-17-47-40.gh-issue-93418.24dJuc.rst new file mode 100644 index 00000000000000..74ad06bfeee7c4 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-06-01-17-47-40.gh-issue-93418.24dJuc.rst @@ -0,0 +1,2 @@ +Fixed an assert where an f-string has an equal sign '=' following an +expression, but there's no trailing brace. For example, f"{i=". diff --git a/Parser/string_parser.c b/Parser/string_parser.c index dac8dbb846471a..80f158b5a65be3 100644 --- a/Parser/string_parser.c +++ b/Parser/string_parser.c @@ -740,7 +740,9 @@ fstring_find_expr(Parser *p, const char **str, const char *end, int raw, int rec while (Py_ISSPACE(**str)) { *str += 1; } - + if (*str >= end) { + goto unexpected_end_of_string; + } /* Set *expr_text to the text of the expression. */ *expr_text = PyUnicode_FromStringAndSize(expr_start, *str-expr_start); if (!*expr_text) { From 9cdfd1b01aee8bd624c2fb5f5447e0ad5858ff03 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 3 Jun 2022 07:08:21 -0700 Subject: [PATCH 231/237] test.pythoninfo: Fix typo, Py_REF_DEBUG => Py_TRACE_REFS (GH-93467) (cherry picked from commit d8f40ead92b5a973cff3a30482a7659d3b46b1ba) Co-authored-by: Victor Stinner --- Lib/test/pythoninfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index 479e60b16b691b..eef34f08121811 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -142,7 +142,7 @@ def collect_sys(info_add): text = 'Yes (sys.getobjects() present)' else: text = 'No (sys.getobjects() missing)' - info_add('build.Py_REF_DEBUG', text) + info_add('build.Py_TRACE_REFS', text) def collect_platform(info_add): From b382bf50c53e6eab09f3e3bf0802ab052cb0289d Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 3 Jun 2022 14:53:00 -0700 Subject: [PATCH 232/237] gh-93156 - fix negative indexing into absolute `pathlib.PurePath().parents` (GH-93273) When a `_PathParents` object has a drive or a root, the length of the object is *one less* than than the length of `self._parts`, which resulted in an off-by-one error when `path.parents[-n]` was fed through to `self._parts[:-n - 1]`. In particular, `path.parents[-1]` was a malformed path object with spooky properties. This is addressed by adding `len(self)` to negative indices. (cherry picked from commit f32e6b48d12834ba3bde01ec21c14da33abd26d6) Co-authored-by: Barney Gale --- Lib/pathlib.py | 2 ++ Lib/test/test_pathlib.py | 5 +++++ .../Library/2022-05-26-23-10-55.gh-issue-93156.4XfDVN.rst | 2 ++ 3 files changed, 9 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2022-05-26-23-10-55.gh-issue-93156.4XfDVN.rst diff --git a/Lib/pathlib.py b/Lib/pathlib.py index 621fba0e75c0f7..97b23ca45a3a19 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -528,6 +528,8 @@ def __getitem__(self, idx): if idx >= len(self) or idx < -len(self): raise IndexError(idx) + if idx < 0: + idx += len(self) return self._pathcls._from_parsed_parts(self._drv, self._root, self._parts[:-idx - 1]) diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 555c7ee795bd12..bf3fc5fb249d21 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -463,6 +463,9 @@ def test_parents_common(self): self.assertEqual(par[0], P('/a/b')) self.assertEqual(par[1], P('/a')) self.assertEqual(par[2], P('/')) + self.assertEqual(par[-1], P('/')) + self.assertEqual(par[-2], P('/a')) + self.assertEqual(par[-3], P('/a/b')) self.assertEqual(par[0:1], (P('/a/b'),)) self.assertEqual(par[:2], (P('/a/b'), P('/a'))) self.assertEqual(par[:-1], (P('/a/b'), P('/a'))) @@ -470,6 +473,8 @@ def test_parents_common(self): self.assertEqual(par[::2], (P('/a/b'), P('/'))) self.assertEqual(par[::-1], (P('/'), P('/a'), P('/a/b'))) self.assertEqual(list(par), [P('/a/b'), P('/a'), P('/')]) + with self.assertRaises(IndexError): + par[-4] with self.assertRaises(IndexError): par[3] diff --git a/Misc/NEWS.d/next/Library/2022-05-26-23-10-55.gh-issue-93156.4XfDVN.rst b/Misc/NEWS.d/next/Library/2022-05-26-23-10-55.gh-issue-93156.4XfDVN.rst new file mode 100644 index 00000000000000..165baa08aaab14 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-05-26-23-10-55.gh-issue-93156.4XfDVN.rst @@ -0,0 +1,2 @@ +Accessing the :attr:`pathlib.PurePath.parents` sequence of an absolute path +using negative index values produced incorrect results. From 7b3cf3a2884b130c519fbe271e4d2a762248c2a0 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 3 Jun 2022 20:38:54 -0700 Subject: [PATCH 233/237] gh-92886: Fix test that fails when running with `-O` in `test_imaplib.py` (GH-93237) (cherry picked from commit 8150b8cf7fe09d601246f5bdc6456a0e31f31bca) Co-authored-by: jackh-ncl <1750152+jackh-ncl@users.noreply.github.com> --- Lib/test/test_imaplib.py | 1 + .../next/Tests/2022-05-25-23-07-15.gh-issue-92886.Aki63_.rst | 1 + 2 files changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Tests/2022-05-25-23-07-15.gh-issue-92886.Aki63_.rst diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py index 30b553746af11a..b5c78a5d49c524 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -936,6 +936,7 @@ def test_with_statement_logout(self): @threading_helper.reap_threads @cpython_only + @unittest.skipUnless(__debug__, "Won't work if __debug__ is False") def test_dump_ur(self): # See: http://bugs.python.org/issue26543 untagged_resp_dict = {'READ-WRITE': [b'']} diff --git a/Misc/NEWS.d/next/Tests/2022-05-25-23-07-15.gh-issue-92886.Aki63_.rst b/Misc/NEWS.d/next/Tests/2022-05-25-23-07-15.gh-issue-92886.Aki63_.rst new file mode 100644 index 00000000000000..581f6bfea24b6e --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-05-25-23-07-15.gh-issue-92886.Aki63_.rst @@ -0,0 +1 @@ +Fixing tests that fail when running with optimizations (``-O``) in ``test_imaplib.py``. From 60adc4b92a8a6fe115a023c8f639a6de4730fac1 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 4 Jun 2022 12:23:22 -0700 Subject: [PATCH 234/237] Fix missing word in sys.float_info docstring (GH-93489) (GH-93496) (cherry picked from commit e12f34b6d8200508bd50cdc9c6c5637732ff56e7) Co-authored-by: Mark Dickinson Co-authored-by: Mark Dickinson --- Objects/floatobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 2e02f37f4a580a..5af26787731140 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -64,7 +64,7 @@ static PyStructSequence_Field floatinfo_fields[] = { {"min_exp", "DBL_MIN_EXP -- minimum int e such that radix**(e-1) " "is a normalized float"}, {"min_10_exp", "DBL_MIN_10_EXP -- minimum int e such that 10**e is " - "a normalized"}, + "a normalized float"}, {"dig", "DBL_DIG -- maximum number of decimal digits that " "can be faithfully represented in a float"}, {"mant_dig", "DBL_MANT_DIG -- mantissa digits"}, From 2f8aae38b9ce19dfd00356927a68cd00366331bc Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 5 Jun 2022 02:39:03 -0700 Subject: [PATCH 235/237] gh-89973: Fix re.error in the fnmatch module. (GH-93072) Character ranges with upper bound less that lower bound (e.g. [c-a]) are now interpreted as empty ranges, for compatibility with other glob pattern implementations. Previously it was re.error. (cherry picked from commit 0902c3d8edf7ef67972dd95f6a21670f5d1a4251) Co-authored-by: Serhiy Storchaka --- Lib/fnmatch.py | 30 +++-- Lib/test/test_fnmatch.py | 114 ++++++++++++++++++ ...2-05-22-16-08-01.gh-issue-89973.jc-Q4g.rst | 3 + 3 files changed, 140 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-05-22-16-08-01.gh-issue-89973.jc-Q4g.rst diff --git a/Lib/fnmatch.py b/Lib/fnmatch.py index 7c52c23067d40f..fee59bf73ff264 100644 --- a/Lib/fnmatch.py +++ b/Lib/fnmatch.py @@ -108,7 +108,7 @@ def translate(pat): add('\\[') else: stuff = pat[i:j] - if '--' not in stuff: + if '-' not in stuff: stuff = stuff.replace('\\', r'\\') else: chunks = [] @@ -120,7 +120,16 @@ def translate(pat): chunks.append(pat[i:k]) i = k+1 k = k+3 - chunks.append(pat[i:j]) + chunk = pat[i:j] + if chunk: + chunks.append(chunk) + else: + chunks[-1] += '-' + # Remove empty ranges -- invalid in RE. + for k in range(len(chunks)-1, 0, -1): + if chunks[k-1][-1] > chunks[k][0]: + chunks[k-1] = chunks[k-1][:-1] + chunks[k][1:] + del chunks[k] # Escape backslashes and hyphens for set difference (--). # Hyphens that create ranges shouldn't be escaped. stuff = '-'.join(s.replace('\\', r'\\').replace('-', r'\-') @@ -128,11 +137,18 @@ def translate(pat): # Escape set operations (&&, ~~ and ||). stuff = re.sub(r'([&~|])', r'\\\1', stuff) i = j+1 - if stuff[0] == '!': - stuff = '^' + stuff[1:] - elif stuff[0] in ('^', '['): - stuff = '\\' + stuff - add(f'[{stuff}]') + if not stuff: + # Empty range: never match. + add('(?!)') + elif stuff == '!': + # Negated empty range: match any character. + add('.') + else: + if stuff[0] == '!': + stuff = '^' + stuff[1:] + elif stuff[0] in ('^', '['): + stuff = '\\' + stuff + add(f'[{stuff}]') else: add(re.escape(c)) assert i == n diff --git a/Lib/test/test_fnmatch.py b/Lib/test/test_fnmatch.py index 10668e4f6103aa..8e2d274bba2bb3 100644 --- a/Lib/test/test_fnmatch.py +++ b/Lib/test/test_fnmatch.py @@ -2,6 +2,7 @@ import unittest import os +import string import warnings from fnmatch import fnmatch, fnmatchcase, translate, filter @@ -91,6 +92,119 @@ def test_sep(self): check('usr/bin', 'usr\\bin', normsep) check('usr\\bin', 'usr\\bin') + def test_char_set(self): + ignorecase = os.path.normcase('ABC') == os.path.normcase('abc') + check = self.check_match + tescases = string.ascii_lowercase + string.digits + string.punctuation + for c in tescases: + check(c, '[az]', c in 'az') + check(c, '[!az]', c not in 'az') + # Case insensitive. + for c in tescases: + check(c, '[AZ]', (c in 'az') and ignorecase) + check(c, '[!AZ]', (c not in 'az') or not ignorecase) + for c in string.ascii_uppercase: + check(c, '[az]', (c in 'AZ') and ignorecase) + check(c, '[!az]', (c not in 'AZ') or not ignorecase) + # Repeated same character. + for c in tescases: + check(c, '[aa]', c == 'a') + # Special cases. + for c in tescases: + check(c, '[^az]', c in '^az') + check(c, '[[az]', c in '[az') + check(c, r'[!]]', c != ']') + check('[', '[') + check('[]', '[]') + check('[!', '[!') + check('[!]', '[!]') + + def test_range(self): + ignorecase = os.path.normcase('ABC') == os.path.normcase('abc') + normsep = os.path.normcase('\\') == os.path.normcase('/') + check = self.check_match + tescases = string.ascii_lowercase + string.digits + string.punctuation + for c in tescases: + check(c, '[b-d]', c in 'bcd') + check(c, '[!b-d]', c not in 'bcd') + check(c, '[b-dx-z]', c in 'bcdxyz') + check(c, '[!b-dx-z]', c not in 'bcdxyz') + # Case insensitive. + for c in tescases: + check(c, '[B-D]', (c in 'bcd') and ignorecase) + check(c, '[!B-D]', (c not in 'bcd') or not ignorecase) + for c in string.ascii_uppercase: + check(c, '[b-d]', (c in 'BCD') and ignorecase) + check(c, '[!b-d]', (c not in 'BCD') or not ignorecase) + # Upper bound == lower bound. + for c in tescases: + check(c, '[b-b]', c == 'b') + # Special cases. + for c in tescases: + check(c, '[!-#]', c not in '-#') + check(c, '[!--.]', c not in '-.') + check(c, '[^-`]', c in '^_`') + if not (normsep and c == '/'): + check(c, '[[-^]', c in r'[\]^') + check(c, r'[\-^]', c in r'\]^') + check(c, '[b-]', c in '-b') + check(c, '[!b-]', c not in '-b') + check(c, '[-b]', c in '-b') + check(c, '[!-b]', c not in '-b') + check(c, '[-]', c in '-') + check(c, '[!-]', c not in '-') + # Upper bound is less that lower bound: error in RE. + for c in tescases: + check(c, '[d-b]', False) + check(c, '[!d-b]', True) + check(c, '[d-bx-z]', c in 'xyz') + check(c, '[!d-bx-z]', c not in 'xyz') + check(c, '[d-b^-`]', c in '^_`') + if not (normsep and c == '/'): + check(c, '[d-b[-^]', c in r'[\]^') + + def test_sep_in_char_set(self): + normsep = os.path.normcase('\\') == os.path.normcase('/') + check = self.check_match + check('/', r'[/]') + check('\\', r'[\]') + check('/', r'[\]', normsep) + check('\\', r'[/]', normsep) + check('[/]', r'[/]', False) + check(r'[\\]', r'[/]', False) + check('\\', r'[\t]') + check('/', r'[\t]', normsep) + check('t', r'[\t]') + check('\t', r'[\t]', False) + + def test_sep_in_range(self): + normsep = os.path.normcase('\\') == os.path.normcase('/') + check = self.check_match + check('a/b', 'a[.-0]b', not normsep) + check('a\\b', 'a[.-0]b', False) + check('a\\b', 'a[Z-^]b', not normsep) + check('a/b', 'a[Z-^]b', False) + + check('a/b', 'a[/-0]b', not normsep) + check(r'a\b', 'a[/-0]b', False) + check('a[/-0]b', 'a[/-0]b', False) + check(r'a[\-0]b', 'a[/-0]b', False) + + check('a/b', 'a[.-/]b') + check(r'a\b', 'a[.-/]b', normsep) + check('a[.-/]b', 'a[.-/]b', False) + check(r'a[.-\]b', 'a[.-/]b', False) + + check(r'a\b', r'a[\-^]b') + check('a/b', r'a[\-^]b', normsep) + check(r'a[\-^]b', r'a[\-^]b', False) + check('a[/-^]b', r'a[\-^]b', False) + + check(r'a\b', r'a[Z-\]b', not normsep) + check('a/b', r'a[Z-\]b', False) + check(r'a[Z-\]b', r'a[Z-\]b', False) + check('a[Z-/]b', r'a[Z-\]b', False) + def test_warnings(self): with warnings.catch_warnings(): warnings.simplefilter('error', Warning) diff --git a/Misc/NEWS.d/next/Library/2022-05-22-16-08-01.gh-issue-89973.jc-Q4g.rst b/Misc/NEWS.d/next/Library/2022-05-22-16-08-01.gh-issue-89973.jc-Q4g.rst new file mode 100644 index 00000000000000..7e61fd7d46a0bb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-05-22-16-08-01.gh-issue-89973.jc-Q4g.rst @@ -0,0 +1,3 @@ +Fix :exc:`re.error` raised in :mod:`fnmatch` if the pattern contains a +character range with upper bound lower than lower bound (e.g. ``[c-a]``). +Now such ranges are interpreted as empty ranges. From fd247db57a536d62902b296af599505298fd1e70 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 5 Jun 2022 18:42:21 -0700 Subject: [PATCH 236/237] gh-93247: Fix assert function in asyncio locks test (GH-93248) (cherry picked from commit 9081bbd036934ab435291db9d32d02fd42282951) Co-authored-by: Cyker Way --- Lib/test/test_asyncio/test_locks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_asyncio/test_locks.py b/Lib/test/test_asyncio/test_locks.py index c5e3fdcbc955a5..167ae700e5c077 100644 --- a/Lib/test/test_asyncio/test_locks.py +++ b/Lib/test/test_asyncio/test_locks.py @@ -866,7 +866,7 @@ async def c4(result): self.assertTrue(t1.result()) race_tasks = [t2, t3, t4] done_tasks = [t for t in race_tasks if t.done() and t.result()] - self.assertTrue(2, len(done_tasks)) + self.assertEqual(2, len(done_tasks)) # cleanup locked semaphore sem.release() From f37715396786fd4055f5891aa16774ede26392ff Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Mon, 6 Jun 2022 12:52:40 +0100 Subject: [PATCH 237/237] Python 3.10.5 --- Include/patchlevel.h | 4 +- Lib/pydoc_data/topics.py | 60 +- Misc/NEWS.d/3.10.5.rst | 824 ++++++++++++++++++ .../2022-03-23-20-01-16.bpo-47103.b4-00F.rst | 2 - .../2021-09-28-10-58-30.bpo-36819.cyV50C.rst | 2 - .../2022-03-08-21-59-57.bpo-46962.UomDfz.rst | 10 - .../2022-03-11-09-39-01.bpo-39829.mlW3Su.rst | 1 - .../2022-03-26-15-45-57.bpo-47117.60W6GQ.rst | 2 - .../2022-03-30-02-36-25.bpo-46775.e3Oxqf.rst | 3 - .../2022-03-31-15-37-02.bpo-47182.e_4SsC.rst | 2 - .../2022-04-05-11-29-21.bpo-47212.leF4pz.rst | 3 - ...2-04-10-22-57-27.gh-issue-91421.dHhv6U.rst | 1 - ...2-04-28-23-37-30.gh-issue-92036.GZJAC9.rst | 5 - ...2-05-01-10-58-38.gh-issue-92112.lLJemu.rst | 1 - ...2-05-12-09-38-20.gh-issue-92311.VEgtts.rst | 1 - ...2-05-21-23-21-37.gh-issue-93065.5I18WC.rst | 5 - ...2-05-22-02-37-50.gh-issue-93061.r70Imp.rst | 1 - ...2-05-25-04-07-22.gh-issue-91924.-UyO4q.rst | 2 - ...2-06-01-17-47-40.gh-issue-93418.24dJuc.rst | 2 - .../2017-12-10-19-13-39.bpo-13553.gQbZs4.rst | 1 - .../2019-09-12-08-28-17.bpo-38056.6ktYkc.rst | 1 - .../2020-07-07-22-54-51.bpo-41233.lyUJ8L.rst | 1 - .../2020-11-12-21-26-31.bpo-42340.apumUL.rst | 3 - .../2021-11-12-11-03-55.bpo-45790.6yuhe8.rst | 2 - .../2022-01-13-16-03-15.bpo-40838.k3NVCf.rst | 2 - .../2022-01-23-20-44-53.bpo-26792.dQ1v1W.rst | 2 - .../2022-03-08-22-10-38.bpo-46962.FIVe9I.rst | 4 - .../2022-03-28-12-29-42.bpo-47138.2B4N-k.rst | 1 - .../2022-04-01-09-28-31.bpo-38668.j4mrqW.rst | 3 - .../2022-04-10-20-28-20.bpo-44347.Q1m3DM.rst | 1 - ...2-04-19-20-16-00.gh-issue-91547.LsNWER.rst | 1 - ...2-04-23-00-22-54.gh-issue-91783.N09dRR.rst | 2 - ...2-04-24-22-09-31.gh-issue-91888.kTjJLx.rst | 1 - ...2-05-18-23-58-26.gh-issue-92240.bHvYiz.rst | 2 - ...2-05-26-11-33-23.gh-issue-86438.kEGGmK.rst | 3 - .../2019-06-22-11-01-45.bpo-36073.ED8mB9.rst | 2 - .../2021-05-22-07-58-59.bpo-42627.EejtD0.rst | 1 - .../2021-07-26-10-46-49.bpo-44493.xp3CRH.rst | 3 - .../2021-09-08-16-21-03.bpo-45138.yghUrK.rst | 3 - .../2022-01-09-14-23-00.bpo-28249.4dzB80.rst | 2 - .../2022-01-17-16-53-30.bpo-46415.6wSYg-.rst | 2 - .../2022-02-09-23-44-27.bpo-45393.9v5Y8U.rst | 2 - .../2022-02-18-20-09-29.bpo-46787.juwWc0.rst | 1 - .../2022-03-23-15-31-02.bpo-47101.rVSld-.rst | 4 - .../2022-03-27-12-40-16.bpo-43323.9mFPuI.rst | 2 - .../2022-03-28-13-35-50.bpo-27929.j5mAmV.rst | 3 - .../2022-03-30-01-17-43.bpo-47151.z-nQkR.rst | 3 - .../2022-04-03-19-40-09.bpo-39064.76PbIz.rst | 2 - .../2022-04-08-14-30-53.bpo-47260.TtcNxI.rst | 2 - ...2-04-15-13-16-25.gh-issue-91581.9OGsrN.rst | 6 - ...2-04-15-18-38-21.gh-issue-91575.fSyAxS.rst | 2 - ...2-04-15-22-07-36.gh-issue-90622.0C6l8h.rst | 4 - ...2-04-16-05-12-13.gh-issue-91595.CocJBv.rst | 1 - ...2-04-18-16-31-33.gh-issue-90568.9kiU7o.rst | 3 - ...2-04-19-04-33-39.gh-issue-91676.ceQBwh.rst | 4 - ...2-04-19-17-30-17.gh-issue-91700.MRJi6m.rst | 4 - ...2-04-20-09-49-33.gh-issue-91734.4Dj4Gy.rst | 1 - ...2-04-23-03-24-00.gh-issue-91832.TyLi65.rst | 1 - ...2-04-25-10-23-01.gh-issue-91810.DOHa6B.rst | 5 - ...2-04-25-14-18-01.gh-issue-91910.kY-JR0.rst | 1 - ...2-04-26-00-10-06.gh-issue-91401.mddRC8.rst | 5 - .../2022-04-26-19-01-13.bpo-47029.qkT42X.rst | 4 - ...2-04-30-10-53-10.gh-issue-92049.5SEKoh.rst | 2 - ...2-05-09-09-28-02.gh-issue-92530.M4Q1RS.rst | 2 - ...2-05-11-14-34-09.gh-issue-91581.glkou2.rst | 5 - ...2-05-16-14-35-39.gh-issue-92839.owSMyo.rst | 1 - ...2-05-20-15-52-43.gh-issue-93010.WF-cAc.rst | 1 - ...2-05-22-16-08-01.gh-issue-89973.jc-Q4g.rst | 3 - ...2-05-26-23-10-55.gh-issue-93156.4XfDVN.rst | 2 - .../2022-01-24-21-31-09.bpo-29890.zEG-ra.rst | 2 - .../2022-03-23-22-45-51.bpo-47104._esUq8.rst | 2 - .../2022-04-03-14-38-21.bpo-47205.hbbTnh.rst | 2 - ...2-04-16-17-54-05.gh-issue-91607.FnXjtW.rst | 1 - ...2-04-25-11-16-36.gh-issue-91904.13Uvrz.rst | 2 - ...2-05-12-05-51-06.gh-issue-92670.7L43Z_.rst | 3 - ...2-05-25-23-07-15.gh-issue-92886.Aki63_.rst | 1 - ...2-04-20-14-26-14.gh-issue-91583.200qI0.rst | 2 - .../2020-06-04-10-42-04.bpo-40859.isKSw7.rst | 1 - .../2022-03-13-20-35-41.bpo-46785.Pnknyl.rst | 1 - .../2022-04-01-14-57-40.bpo-47194.IB0XL4.rst | 1 - ...2-05-19-14-01-30.gh-issue-92984.Dsxnlr.rst | 1 - README.rst | 2 +- 82 files changed, 856 insertions(+), 215 deletions(-) create mode 100644 Misc/NEWS.d/3.10.5.rst delete mode 100644 Misc/NEWS.d/next/Build/2022-03-23-20-01-16.bpo-47103.b4-00F.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2021-09-28-10-58-30.bpo-36819.cyV50C.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-03-08-21-59-57.bpo-46962.UomDfz.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-03-11-09-39-01.bpo-39829.mlW3Su.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-03-26-15-45-57.bpo-47117.60W6GQ.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-03-30-02-36-25.bpo-46775.e3Oxqf.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-03-31-15-37-02.bpo-47182.e_4SsC.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-04-05-11-29-21.bpo-47212.leF4pz.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-04-10-22-57-27.gh-issue-91421.dHhv6U.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-04-28-23-37-30.gh-issue-92036.GZJAC9.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-05-01-10-58-38.gh-issue-92112.lLJemu.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-05-12-09-38-20.gh-issue-92311.VEgtts.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-05-21-23-21-37.gh-issue-93065.5I18WC.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-05-22-02-37-50.gh-issue-93061.r70Imp.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-05-25-04-07-22.gh-issue-91924.-UyO4q.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-06-01-17-47-40.gh-issue-93418.24dJuc.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2017-12-10-19-13-39.bpo-13553.gQbZs4.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2019-09-12-08-28-17.bpo-38056.6ktYkc.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2020-07-07-22-54-51.bpo-41233.lyUJ8L.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2020-11-12-21-26-31.bpo-42340.apumUL.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2021-11-12-11-03-55.bpo-45790.6yuhe8.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2022-01-13-16-03-15.bpo-40838.k3NVCf.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2022-01-23-20-44-53.bpo-26792.dQ1v1W.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2022-03-08-22-10-38.bpo-46962.FIVe9I.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2022-03-28-12-29-42.bpo-47138.2B4N-k.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2022-04-01-09-28-31.bpo-38668.j4mrqW.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2022-04-10-20-28-20.bpo-44347.Q1m3DM.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2022-04-19-20-16-00.gh-issue-91547.LsNWER.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2022-04-23-00-22-54.gh-issue-91783.N09dRR.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2022-04-24-22-09-31.gh-issue-91888.kTjJLx.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2022-05-18-23-58-26.gh-issue-92240.bHvYiz.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2022-05-26-11-33-23.gh-issue-86438.kEGGmK.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-06-22-11-01-45.bpo-36073.ED8mB9.rst delete mode 100644 Misc/NEWS.d/next/Library/2021-05-22-07-58-59.bpo-42627.EejtD0.rst delete mode 100644 Misc/NEWS.d/next/Library/2021-07-26-10-46-49.bpo-44493.xp3CRH.rst delete mode 100644 Misc/NEWS.d/next/Library/2021-09-08-16-21-03.bpo-45138.yghUrK.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-01-09-14-23-00.bpo-28249.4dzB80.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-01-17-16-53-30.bpo-46415.6wSYg-.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-02-09-23-44-27.bpo-45393.9v5Y8U.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-02-18-20-09-29.bpo-46787.juwWc0.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-03-27-12-40-16.bpo-43323.9mFPuI.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-03-28-13-35-50.bpo-27929.j5mAmV.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-04-03-19-40-09.bpo-39064.76PbIz.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-04-08-14-30-53.bpo-47260.TtcNxI.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-04-15-13-16-25.gh-issue-91581.9OGsrN.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-04-15-18-38-21.gh-issue-91575.fSyAxS.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-04-15-22-07-36.gh-issue-90622.0C6l8h.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-04-16-05-12-13.gh-issue-91595.CocJBv.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-04-18-16-31-33.gh-issue-90568.9kiU7o.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-04-19-04-33-39.gh-issue-91676.ceQBwh.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-04-19-17-30-17.gh-issue-91700.MRJi6m.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-04-20-09-49-33.gh-issue-91734.4Dj4Gy.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-04-23-03-24-00.gh-issue-91832.TyLi65.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-04-25-10-23-01.gh-issue-91810.DOHa6B.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-04-25-14-18-01.gh-issue-91910.kY-JR0.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-04-26-00-10-06.gh-issue-91401.mddRC8.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-04-26-19-01-13.bpo-47029.qkT42X.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-04-30-10-53-10.gh-issue-92049.5SEKoh.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-05-09-09-28-02.gh-issue-92530.M4Q1RS.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-05-11-14-34-09.gh-issue-91581.glkou2.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-05-16-14-35-39.gh-issue-92839.owSMyo.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-05-20-15-52-43.gh-issue-93010.WF-cAc.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-05-22-16-08-01.gh-issue-89973.jc-Q4g.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-05-26-23-10-55.gh-issue-93156.4XfDVN.rst delete mode 100644 Misc/NEWS.d/next/Tests/2022-01-24-21-31-09.bpo-29890.zEG-ra.rst delete mode 100644 Misc/NEWS.d/next/Tests/2022-03-23-22-45-51.bpo-47104._esUq8.rst delete mode 100644 Misc/NEWS.d/next/Tests/2022-04-03-14-38-21.bpo-47205.hbbTnh.rst delete mode 100644 Misc/NEWS.d/next/Tests/2022-04-16-17-54-05.gh-issue-91607.FnXjtW.rst delete mode 100644 Misc/NEWS.d/next/Tests/2022-04-25-11-16-36.gh-issue-91904.13Uvrz.rst delete mode 100644 Misc/NEWS.d/next/Tests/2022-05-12-05-51-06.gh-issue-92670.7L43Z_.rst delete mode 100644 Misc/NEWS.d/next/Tests/2022-05-25-23-07-15.gh-issue-92886.Aki63_.rst delete mode 100644 Misc/NEWS.d/next/Tools-Demos/2022-04-20-14-26-14.gh-issue-91583.200qI0.rst delete mode 100644 Misc/NEWS.d/next/Windows/2020-06-04-10-42-04.bpo-40859.isKSw7.rst delete mode 100644 Misc/NEWS.d/next/Windows/2022-03-13-20-35-41.bpo-46785.Pnknyl.rst delete mode 100644 Misc/NEWS.d/next/Windows/2022-04-01-14-57-40.bpo-47194.IB0XL4.rst delete mode 100644 Misc/NEWS.d/next/Windows/2022-05-19-14-01-30.gh-issue-92984.Dsxnlr.rst diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 3c4c0debce4cc2..2d30d350da8502 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -18,12 +18,12 @@ /*--start constants--*/ #define PY_MAJOR_VERSION 3 #define PY_MINOR_VERSION 10 -#define PY_MICRO_VERSION 4 +#define PY_MICRO_VERSION 5 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.10.4+" +#define PY_VERSION "3.10.5" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index 76db0426df3318..17f0cb4f2042f3 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Wed Mar 23 20:11:40 2022 +# Autogenerated by Sphinx on Mon Jun 6 12:53:10 2022 topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -93,11 +93,7 @@ ' optionally in parentheses, the object is assigned to that ' 'target.\n' '\n' - '* Else: The object must be an iterable with the same number of ' - 'items\n' - ' as there are targets in the target list, and the items are ' - 'assigned,\n' - ' from left to right, to the corresponding targets.\n' + '* Else:\n' '\n' ' * If the target list contains one target prefixed with an ' 'asterisk,\n' @@ -4812,7 +4808,10 @@ 'is\n' 'applied to separating the commands; the input is split at the ' 'first\n' - '";;" pair, even if it is in the middle of a quoted string.\n' + '";;" pair, even if it is in the middle of a quoted string. A\n' + 'workaround for strings with double semicolons is to use ' + 'implicit\n' + 'string concatenation "\';\'\';\'" or "";"";"".\n' '\n' 'If a file ".pdbrc" exists in the user’s home directory or in ' 'the\n' @@ -7269,12 +7268,12 @@ 'Examples:\n' '\n' ' import foo # foo imported and bound locally\n' - ' import foo.bar.baz # foo.bar.baz imported, foo bound ' - 'locally\n' - ' import foo.bar.baz as fbb # foo.bar.baz imported and bound as ' - 'fbb\n' - ' from foo.bar import baz # foo.bar.baz imported and bound as ' - 'baz\n' + ' import foo.bar.baz # foo, foo.bar, and foo.bar.baz ' + 'imported, foo bound locally\n' + ' import foo.bar.baz as fbb # foo, foo.bar, and foo.bar.baz ' + 'imported, foo.bar.baz bound as fbb\n' + ' from foo.bar import baz # foo, foo.bar, and foo.bar.baz ' + 'imported, foo.bar.baz bound as baz\n' ' from foo import attr # foo imported and foo.attr bound as ' 'attr\n' '\n' @@ -8189,7 +8188,7 @@ '| "x(arguments...)", "x.attribute" | ' 'attribute reference |\n' '+-------------------------------------------------+---------------------------------------+\n' - '| "await" "x" | ' + '| "await x" | ' 'Await expression |\n' '+-------------------------------------------------+---------------------------------------+\n' '| "**" | ' @@ -8225,7 +8224,7 @@ '| ">=", "!=", "==" | ' 'tests and identity tests |\n' '+-------------------------------------------------+---------------------------------------+\n' - '| "not" "x" | ' + '| "not x" | ' 'Boolean NOT |\n' '+-------------------------------------------------+---------------------------------------+\n' '| "and" | ' @@ -11988,9 +11987,13 @@ ' >>> "they\'re bill\'s friends from the UK".title()\n' ' "They\'Re Bill\'S Friends From The Uk"\n' '\n' - ' A workaround for apostrophes can be constructed using ' - 'regular\n' - ' expressions:\n' + ' The "string.capwords()" function does not have this ' + 'problem, as it\n' + ' splits words on spaces only.\n' + '\n' + ' Alternatively, a workaround for apostrophes can be ' + 'constructed\n' + ' using regular expressions:\n' '\n' ' >>> import re\n' ' >>> def titlecase(s):\n' @@ -12112,12 +12115,15 @@ 'single quotes ("\'") or double quotes ("""). They can also be ' 'enclosed\n' 'in matching groups of three single or double quotes (these are\n' - 'generally referred to as *triple-quoted strings*). The ' - 'backslash\n' - '("\\") character is used to escape characters that otherwise have ' - 'a\n' - 'special meaning, such as newline, backslash itself, or the quote\n' + 'generally referred to as *triple-quoted strings*). The backslash ' + '("\\")\n' + 'character is used to give special meaning to otherwise ordinary\n' + 'characters like "n", which means ‘newline’ when escaped ("\\n"). ' + 'It can\n' + 'also be used to escape characters that otherwise have a special\n' + 'meaning, such as newline, backslash itself, or the quote ' 'character.\n' + 'See escape sequences below for examples.\n' '\n' 'Bytes literals are always prefixed with "\'b\'" or "\'B\'"; they ' 'produce\n' @@ -13735,14 +13741,6 @@ 'unwise to use\n' 'them as dictionary keys.)\n' '\n' - 'Dictionaries can be created by placing a comma-separated ' - 'list of "key:\n' - 'value" pairs within braces, for example: "{\'jack\': 4098, ' - "'sjoerd':\n" - '4127}" or "{4098: \'jack\', 4127: \'sjoerd\'}", or by the ' - '"dict"\n' - 'constructor.\n' - '\n' 'class dict(**kwargs)\n' 'class dict(mapping, **kwargs)\n' 'class dict(iterable, **kwargs)\n' diff --git a/Misc/NEWS.d/3.10.5.rst b/Misc/NEWS.d/3.10.5.rst new file mode 100644 index 00000000000000..afb3582c571e05 --- /dev/null +++ b/Misc/NEWS.d/3.10.5.rst @@ -0,0 +1,824 @@ +.. date: 2022-06-01-17-47-40 +.. gh-issue: 93418 +.. nonce: 24dJuc +.. release date: 2022-06-06 +.. section: Core and Builtins + +Fixed an assert where an f-string has an equal sign '=' following an +expression, but there's no trailing brace. For example, f"{i=". + +.. + +.. date: 2022-05-25-04-07-22 +.. gh-issue: 91924 +.. nonce: -UyO4q +.. section: Core and Builtins + +Fix ``__ltrace__`` debug feature if the stdout encoding is not UTF-8. Patch +by Victor Stinner. + +.. + +.. date: 2022-05-22-02-37-50 +.. gh-issue: 93061 +.. nonce: r70Imp +.. section: Core and Builtins + +Backward jumps after ``async for`` loops are no longer given dubious line +numbers. + +.. + +.. date: 2022-05-21-23-21-37 +.. gh-issue: 93065 +.. nonce: 5I18WC +.. section: Core and Builtins + +Fix contextvars HAMT implementation to handle iteration over deep trees. + +The bug was discovered and fixed by Eli Libman. See +`MagicStack/immutables#84 +`_ for more details. + +.. + +.. date: 2022-05-12-09-38-20 +.. gh-issue: 92311 +.. nonce: VEgtts +.. section: Core and Builtins + +Fixed a bug where setting ``frame.f_lineno`` to jump over a list +comprehension could misbehave or crash. + +.. + +.. date: 2022-05-01-10-58-38 +.. gh-issue: 92112 +.. nonce: lLJemu +.. section: Core and Builtins + +Fix crash triggered by an evil custom ``mro()`` on a metaclass. + +.. + +.. date: 2022-04-28-23-37-30 +.. gh-issue: 92036 +.. nonce: GZJAC9 +.. section: Core and Builtins + +Fix a crash in subinterpreters related to the garbage collector. When a +subinterpreter is deleted, untrack all objects tracked by its GC. To prevent +a crash in deallocator functions expecting objects to be tracked by the GC, +leak a strong reference to these objects on purpose, so they are never +deleted and their deallocator functions are not called. Patch by Victor +Stinner. + +.. + +.. date: 2022-04-10-22-57-27 +.. gh-issue: 91421 +.. nonce: dHhv6U +.. section: Core and Builtins + +Fix a potential integer overflow in _Py_DecodeUTF8Ex. + +.. + +.. bpo: 47212 +.. date: 2022-04-05-11-29-21 +.. nonce: leF4pz +.. section: Core and Builtins + +Raise :exc:`IndentationError` instead of :exc:`SyntaxError` for a bare +``except`` with no following indent. Improve :exc:`SyntaxError` locations +for an un-parenthesized generator used as arguments. Patch by Matthieu +Dartiailh. + +.. + +.. bpo: 47182 +.. date: 2022-03-31-15-37-02 +.. nonce: e_4SsC +.. section: Core and Builtins + +Fix a crash when using a named unicode character like ``"\N{digit nine}"`` +after the main interpreter has been initialized a second time. + +.. + +.. bpo: 46775 +.. date: 2022-03-30-02-36-25 +.. nonce: e3Oxqf +.. section: Core and Builtins + +Some Windows system error codes(>= 10000) are now mapped into the correct +errno and may now raise a subclass of :exc:`OSError`. Patch by Dong-hee Na. + +.. + +.. bpo: 47117 +.. date: 2022-03-26-15-45-57 +.. nonce: 60W6GQ +.. section: Core and Builtins + +Fix a crash if we fail to decode characters in interactive mode if the +tokenizer buffers are uninitialized. Patch by Pablo Galindo. + +.. + +.. bpo: 39829 +.. date: 2022-03-11-09-39-01 +.. nonce: mlW3Su +.. section: Core and Builtins + +Removed the ``__len__()`` call when initializing a list and moved +initializing to ``list_extend``. Patch by Jeremiah Pascual. + +.. + +.. bpo: 46962 +.. date: 2022-03-08-21-59-57 +.. nonce: UomDfz +.. section: Core and Builtins + +Classes and functions that unconditionally declared their docstrings +ignoring the `--without-doc-strings` compilation flag no longer do so. + +The classes affected are :class:`ctypes.UnionType`, +:class:`pickle.PickleBuffer`, :class:`testcapi.RecursingInfinitelyError`, +and :class:`types.GenericAlias`. + +The functions affected are 24 methods in :mod:`ctypes`. + +Patch by Oleg Iarygin. + +.. + +.. bpo: 36819 +.. date: 2021-09-28-10-58-30 +.. nonce: cyV50C +.. section: Core and Builtins + +Fix crashes in built-in encoders with error handlers that return position +less or equal than the starting position of non-encodable characters. + +.. + +.. date: 2022-05-26-23-10-55 +.. gh-issue: 93156 +.. nonce: 4XfDVN +.. section: Library + +Accessing the :attr:`pathlib.PurePath.parents` sequence of an absolute path +using negative index values produced incorrect results. + +.. + +.. date: 2022-05-22-16-08-01 +.. gh-issue: 89973 +.. nonce: jc-Q4g +.. section: Library + +Fix :exc:`re.error` raised in :mod:`fnmatch` if the pattern contains a +character range with upper bound lower than lower bound (e.g. ``[c-a]``). +Now such ranges are interpreted as empty ranges. + +.. + +.. date: 2022-05-20-15-52-43 +.. gh-issue: 93010 +.. nonce: WF-cAc +.. section: Library + +In a very special case, the email package tried to append the nonexistent +``InvalidHeaderError`` to the defect list. It should have been +``InvalidHeaderDefect``. + +.. + +.. date: 2022-05-16-14-35-39 +.. gh-issue: 92839 +.. nonce: owSMyo +.. section: Library + +Fixed crash resulting from calling bisect.insort() or bisect.insort_left() +with the key argument not equal to None. + +.. + +.. date: 2022-05-11-14-34-09 +.. gh-issue: 91581 +.. nonce: glkou2 +.. section: Library + +:meth:`~datetime.datetime.utcfromtimestamp` no longer attempts to resolve +``fold`` in the pure Python implementation, since the fold is never 1 in +UTC. In addition to being slightly faster in the common case, this also +prevents some errors when the timestamp is close to :attr:`datetime.min +`. Patch by Paul Ganssle. + +.. + +.. date: 2022-05-09-09-28-02 +.. gh-issue: 92530 +.. nonce: M4Q1RS +.. section: Library + +Fix an issue that occurred after interrupting +:func:`threading.Condition.notify`. + +.. + +.. date: 2022-04-30-10-53-10 +.. gh-issue: 92049 +.. nonce: 5SEKoh +.. section: Library + +Forbid pickling constants ``re._constants.SUCCESS`` etc. Previously, +pickling did not fail, but the result could not be unpickled. + +.. + +.. bpo: 47029 +.. date: 2022-04-26-19-01-13 +.. nonce: qkT42X +.. section: Library + +Always close the read end of the pipe used by :class:`multiprocessing.Queue` +*after* the last write of buffered data to the write end of the pipe to +avoid :exc:`BrokenPipeError` at garbage collection and at +:meth:`multiprocessing.Queue.close` calls. Patch by Géry Ogam. + +.. + +.. date: 2022-04-26-00-10-06 +.. gh-issue: 91401 +.. nonce: mddRC8 +.. section: Library + +Provide a fail-safe way to disable :mod:`subprocess` use of ``vfork()`` via +a private ``subprocess._USE_VFORK`` attribute. While there is currently no +known need for this, if you find a need please only set it to ``False``. +File a CPython issue as to why you needed it and link to that from a comment +in your code. This attribute is documented as a footnote in 3.11. + +.. + +.. date: 2022-04-25-14-18-01 +.. gh-issue: 91910 +.. nonce: kY-JR0 +.. section: Library + +Add missing f prefix to f-strings in error messages from the +:mod:`multiprocessing` and :mod:`asyncio` modules. + +.. + +.. date: 2022-04-25-10-23-01 +.. gh-issue: 91810 +.. nonce: DOHa6B +.. section: Library + +:class:`~xml.etree.ElementTree.ElementTree` method +:meth:`~xml.etree.ElementTree.ElementTree.write` and function +:func:`~xml.etree.ElementTree.tostring` now use the text file's encoding +("UTF-8" if not available) instead of locale encoding in XML declaration +when ``encoding="unicode"`` is specified. + +.. + +.. date: 2022-04-23-03-24-00 +.. gh-issue: 91832 +.. nonce: TyLi65 +.. section: Library + +Add ``required`` attribute to :class:`argparse.Action` repr output. + +.. + +.. date: 2022-04-20-09-49-33 +.. gh-issue: 91734 +.. nonce: 4Dj4Gy +.. section: Library + +Fix OSS audio support on Solaris. + +.. + +.. date: 2022-04-19-17-30-17 +.. gh-issue: 91700 +.. nonce: MRJi6m +.. section: Library + +Compilation of regular expression containing a conditional expression +``(?(group)...)`` now raises an appropriate :exc:`re.error` if the group +number refers to not defined group. Previously an internal RuntimeError was +raised. + +.. + +.. date: 2022-04-19-04-33-39 +.. gh-issue: 91676 +.. nonce: ceQBwh +.. section: Library + +Fix :class:`unittest.IsolatedAsyncioTestCase` to shutdown the per test event +loop executor before returning from its ``run`` method so that a not yet +stopped or garbage collected executor state does not persist beyond the +test. + +.. + +.. date: 2022-04-18-16-31-33 +.. gh-issue: 90568 +.. nonce: 9kiU7o +.. section: Library + +Parsing ``\N`` escapes of Unicode Named Character Sequences in a +:mod:`regular expression ` raises now :exc:`re.error` instead of +``TypeError``. + +.. + +.. date: 2022-04-16-05-12-13 +.. gh-issue: 91595 +.. nonce: CocJBv +.. section: Library + +Fix the comparison of character and integer inside +:func:`Tools.gdb.libpython.write_repr`. Patch by Yu Liu. + +.. + +.. date: 2022-04-15-22-07-36 +.. gh-issue: 90622 +.. nonce: 0C6l8h +.. section: Library + +Worker processes for :class:`concurrent.futures.ProcessPoolExecutor` are no +longer spawned on demand (a feature added in 3.9) when the multiprocessing +context start method is ``"fork"`` as that can lead to deadlocks in the +child processes due to a fork happening while threads are running. + +.. + +.. date: 2022-04-15-18-38-21 +.. gh-issue: 91575 +.. nonce: fSyAxS +.. section: Library + +Update case-insensitive matching in the :mod:`re` module to the latest +Unicode version. + +.. + +.. date: 2022-04-15-13-16-25 +.. gh-issue: 91581 +.. nonce: 9OGsrN +.. section: Library + +Remove an unhandled error case in the C implementation of calls to +:meth:`datetime.fromtimestamp ` with no +time zone (i.e. getting a local time from an epoch timestamp). This should +have no user-facing effect other than giving a possibly more accurate error +message when called with timestamps that fall on 10000-01-01 in the local +time. Patch by Paul Ganssle. + +.. + +.. bpo: 47260 +.. date: 2022-04-08-14-30-53 +.. nonce: TtcNxI +.. section: Library + +Fix ``os.closerange()`` potentially being a no-op in a Linux seccomp +sandbox. + +.. + +.. bpo: 39064 +.. date: 2022-04-03-19-40-09 +.. nonce: 76PbIz +.. section: Library + +:class:`zipfile.ZipFile` now raises :exc:`zipfile.BadZipFile` instead of +``ValueError`` when reading a corrupt zip file in which the central +directory offset is negative. + +.. + +.. bpo: 47151 +.. date: 2022-03-30-01-17-43 +.. nonce: z-nQkR +.. section: Library + +When subprocess tries to use vfork, it now falls back to fork if vfork +returns an error. This allows use in situations where vfork isn't allowed by +the OS kernel. + +.. + +.. bpo: 27929 +.. date: 2022-03-28-13-35-50 +.. nonce: j5mAmV +.. section: Library + +Fix :meth:`asyncio.loop.sock_connect` to only resolve names for +:const:`socket.AF_INET` or :const:`socket.AF_INET6` families. Resolution may +not make sense for other families, like :const:`socket.AF_BLUETOOTH` and +:const:`socket.AF_UNIX`. + +.. + +.. bpo: 43323 +.. date: 2022-03-27-12-40-16 +.. nonce: 9mFPuI +.. section: Library + +Fix errors in the :mod:`email` module if the charset itself contains +undecodable/unencodable characters. + +.. + +.. bpo: 47101 +.. date: 2022-03-23-15-31-02 +.. nonce: rVSld- +.. section: Library + +:const:`hashlib.algorithms_available` now lists only algorithms that are +provided by activated crypto providers on OpenSSL 3.0. Legacy algorithms are +not listed unless the legacy provider has been loaded into the default OSSL +context. + +.. + +.. bpo: 46787 +.. date: 2022-02-18-20-09-29 +.. nonce: juwWc0 +.. section: Library + +Fix :class:`concurrent.futures.ProcessPoolExecutor` exception memory leak + +.. + +.. bpo: 45393 +.. date: 2022-02-09-23-44-27 +.. nonce: 9v5Y8U +.. section: Library + +Fix the formatting for ``await x`` and ``not x`` in the operator precedence +table when using the :func:`help` system. + +.. + +.. bpo: 46415 +.. date: 2022-01-17-16-53-30 +.. nonce: 6wSYg- +.. section: Library + +Fix ipaddress.ip_{address,interface,network} raising TypeError instead of +ValueError if given invalid tuple as address parameter. + +.. + +.. bpo: 28249 +.. date: 2022-01-09-14-23-00 +.. nonce: 4dzB80 +.. section: Library + +Set :attr:`doctest.DocTest.lineno` to ``None`` when object does not have +:attr:`__doc__`. + +.. + +.. bpo: 45138 +.. date: 2021-09-08-16-21-03 +.. nonce: yghUrK +.. section: Library + +Fix a regression in the :mod:`sqlite3` trace callback where bound parameters +were not expanded in the passed statement string. The regression was +introduced in Python 3.10 by :issue:`40318`. Patch by Erlend E. Aasland. + +.. + +.. bpo: 44493 +.. date: 2021-07-26-10-46-49 +.. nonce: xp3CRH +.. section: Library + +Add missing terminated NUL in sockaddr_un's length + +This was potentially observable when using non-abstract AF_UNIX datagram +sockets to processes written in another programming language. + +.. + +.. bpo: 42627 +.. date: 2021-05-22-07-58-59 +.. nonce: EejtD0 +.. section: Library + +Fix incorrect parsing of Windows registry proxy settings + +.. + +.. bpo: 36073 +.. date: 2019-06-22-11-01-45 +.. nonce: ED8mB9 +.. section: Library + +Raise :exc:`~sqlite3.ProgrammingError` instead of segfaulting on recursive +usage of cursors in :mod:`sqlite3` converters. Patch by Sergey Fedoseev. + +.. + +.. date: 2022-05-26-11-33-23 +.. gh-issue: 86438 +.. nonce: kEGGmK +.. section: Documentation + +Clarify that :option:`-W` and :envvar:`PYTHONWARNINGS` are matched literally +and case-insensitively, rather than as regular expressions, in +:mod:`warnings`. + +.. + +.. date: 2022-05-18-23-58-26 +.. gh-issue: 92240 +.. nonce: bHvYiz +.. section: Documentation + +Added release dates for "What's New in Python 3.X" for 3.0, 3.1, 3.2, 3.8 +and 3.10 + +.. + +.. date: 2022-04-24-22-09-31 +.. gh-issue: 91888 +.. nonce: kTjJLx +.. section: Documentation + +Add a new ``gh`` role to the documentation to link to GitHub issues. + +.. + +.. date: 2022-04-23-00-22-54 +.. gh-issue: 91783 +.. nonce: N09dRR +.. section: Documentation + +Document security issues concerning the use of the function +:meth:`shutil.unpack_archive` + +.. + +.. date: 2022-04-19-20-16-00 +.. gh-issue: 91547 +.. nonce: LsNWER +.. section: Documentation + +Remove "Undocumented modules" page. + +.. + +.. bpo: 44347 +.. date: 2022-04-10-20-28-20 +.. nonce: Q1m3DM +.. section: Documentation + +Clarify the meaning of *dirs_exist_ok*, a kwarg of :func:`shutil.copytree`. + +.. + +.. bpo: 38668 +.. date: 2022-04-01-09-28-31 +.. nonce: j4mrqW +.. section: Documentation + +Update the introduction to documentation for :mod:`os.path` to remove +warnings that became irrelevant after the implementations of :pep:`383` and +:pep:`529`. + +.. + +.. bpo: 47138 +.. date: 2022-03-28-12-29-42 +.. nonce: 2B4N-k +.. section: Documentation + +Pin Jinja to a version compatible with Sphinx version 3.2.1. + +.. + +.. bpo: 46962 +.. date: 2022-03-08-22-10-38 +.. nonce: FIVe9I +.. section: Documentation + +All docstrings in code snippets are now wrapped into :func:`PyDoc_STR` to +follow the guideline of `PEP 7's Documentation Strings paragraph +`_. Patch +by Oleg Iarygin. + +.. + +.. bpo: 26792 +.. date: 2022-01-23-20-44-53 +.. nonce: dQ1v1W +.. section: Documentation + +Improve the docstrings of :func:`runpy.run_module` and +:func:`runpy.run_path`. Original patch by Andrew Brezovsky. + +.. + +.. bpo: 40838 +.. date: 2022-01-13-16-03-15 +.. nonce: k3NVCf +.. section: Documentation + +Document that :func:`inspect.getdoc`, :func:`inspect.getmodule`, and +:func:`inspect.getsourcefile` might return ``None``. + +.. + +.. bpo: 45790 +.. date: 2021-11-12-11-03-55 +.. nonce: 6yuhe8 +.. section: Documentation + +Adjust inaccurate phrasing in :doc:`../extending/newtypes_tutorial` about +the ``ob_base`` field and the macros used to access its contents. + +.. + +.. bpo: 42340 +.. date: 2020-11-12-21-26-31 +.. nonce: apumUL +.. section: Documentation + +Document that in some circumstances :exc:`KeyboardInterrupt` may cause the +code to enter an inconsistent state. Provided a sample workaround to avoid +it if needed. + +.. + +.. bpo: 41233 +.. date: 2020-07-07-22-54-51 +.. nonce: lyUJ8L +.. section: Documentation + +Link the errnos referenced in ``Doc/library/exceptions.rst`` to their +respective section in ``Doc/library/errno.rst``, and vice versa. Previously +this was only done for EINTR and InterruptedError. Patch by Yan "yyyyyyyan" +Orestes. + +.. + +.. bpo: 38056 +.. date: 2019-09-12-08-28-17 +.. nonce: 6ktYkc +.. section: Documentation + +Overhaul the :ref:`error-handlers` documentation in :mod:`codecs`. + +.. + +.. bpo: 13553 +.. date: 2017-12-10-19-13-39 +.. nonce: gQbZs4 +.. section: Documentation + +Document tkinter.Tk args. + +.. + +.. date: 2022-05-25-23-07-15 +.. gh-issue: 92886 +.. nonce: Aki63_ +.. section: Tests + +Fixing tests that fail when running with optimizations (``-O``) in +``test_imaplib.py``. + +.. + +.. date: 2022-05-12-05-51-06 +.. gh-issue: 92670 +.. nonce: 7L43Z_ +.. section: Tests + +Skip ``test_shutil.TestCopy.test_copyfile_nonexistent_dir`` test on AIX as +the test uses a trailing slash to force the OS consider the path as a +directory, but on AIX the trailing slash has no effect and is considered as +a file. + +.. + +.. date: 2022-04-25-11-16-36 +.. gh-issue: 91904 +.. nonce: 13Uvrz +.. section: Tests + +Fix initialization of :envvar:`PYTHONREGRTEST_UNICODE_GUARD` which prevented +running regression tests on non-UTF-8 locale. + +.. + +.. date: 2022-04-16-17-54-05 +.. gh-issue: 91607 +.. nonce: FnXjtW +.. section: Tests + +Fix ``test_concurrent_futures`` to test the correct multiprocessing start +method context in several cases where the test logic mixed this up. + +.. + +.. bpo: 47205 +.. date: 2022-04-03-14-38-21 +.. nonce: hbbTnh +.. section: Tests + +Skip test for :func:`~os.sched_getaffinity` and +:func:`~os.sched_setaffinity` error case on FreeBSD. + +.. + +.. bpo: 47104 +.. date: 2022-03-23-22-45-51 +.. nonce: _esUq8 +.. section: Tests + +Rewrite :func:`asyncio.to_thread` tests to use +:class:`unittest.IsolatedAsyncioTestCase`. + +.. + +.. bpo: 29890 +.. date: 2022-01-24-21-31-09 +.. nonce: zEG-ra +.. section: Tests + +Add tests for :class:`ipaddress.IPv4Interface` and +:class:`ipaddress.IPv6Interface` construction with tuple arguments. Original +patch and tests by louisom. + +.. + +.. bpo: 47103 +.. date: 2022-03-23-20-01-16 +.. nonce: b4-00F +.. section: Build + +Windows ``PGInstrument`` builds now copy a required DLL into the output +directory, making it easier to run the profile stage of a PGO build. + +.. + +.. date: 2022-05-19-14-01-30 +.. gh-issue: 92984 +.. nonce: Dsxnlr +.. section: Windows + +Explicitly disable incremental linking for non-Debug builds + +.. + +.. bpo: 47194 +.. date: 2022-04-01-14-57-40 +.. nonce: IB0XL4 +.. section: Windows + +Update ``zlib`` to v1.2.12 to resolve CVE-2018-25032. + +.. + +.. bpo: 46785 +.. date: 2022-03-13-20-35-41 +.. nonce: Pnknyl +.. section: Windows + +Fix race condition between :func:`os.stat` and unlinking a file on Windows, +by using errors codes returned by ``FindFirstFileW()`` when appropriate in +``win32_xstat_impl``. + +.. + +.. bpo: 40859 +.. date: 2020-06-04-10-42-04 +.. nonce: isKSw7 +.. section: Windows + +Update Windows build to use xz-5.2.5 + +.. + +.. date: 2022-04-20-14-26-14 +.. gh-issue: 91583 +.. nonce: 200qI0 +.. section: Tools/Demos + +Fix regression in the code generated by Argument Clinic for functions with +the ``defining_class`` parameter. diff --git a/Misc/NEWS.d/next/Build/2022-03-23-20-01-16.bpo-47103.b4-00F.rst b/Misc/NEWS.d/next/Build/2022-03-23-20-01-16.bpo-47103.b4-00F.rst deleted file mode 100644 index c1e01adce0d269..00000000000000 --- a/Misc/NEWS.d/next/Build/2022-03-23-20-01-16.bpo-47103.b4-00F.rst +++ /dev/null @@ -1,2 +0,0 @@ -Windows ``PGInstrument`` builds now copy a required DLL into the output -directory, making it easier to run the profile stage of a PGO build. diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-09-28-10-58-30.bpo-36819.cyV50C.rst b/Misc/NEWS.d/next/Core and Builtins/2021-09-28-10-58-30.bpo-36819.cyV50C.rst deleted file mode 100644 index 32bb55a90e6c4d..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2021-09-28-10-58-30.bpo-36819.cyV50C.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix crashes in built-in encoders with error handlers that return position -less or equal than the starting position of non-encodable characters. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-08-21-59-57.bpo-46962.UomDfz.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-08-21-59-57.bpo-46962.UomDfz.rst deleted file mode 100644 index 395c9b3d8f5260..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-03-08-21-59-57.bpo-46962.UomDfz.rst +++ /dev/null @@ -1,10 +0,0 @@ -Classes and functions that unconditionally declared their docstrings -ignoring the `--without-doc-strings` compilation flag no longer do so. - -The classes affected are :class:`ctypes.UnionType`, -:class:`pickle.PickleBuffer`, :class:`testcapi.RecursingInfinitelyError`, -and :class:`types.GenericAlias`. - -The functions affected are 24 methods in :mod:`ctypes`. - -Patch by Oleg Iarygin. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-11-09-39-01.bpo-39829.mlW3Su.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-11-09-39-01.bpo-39829.mlW3Su.rst deleted file mode 100644 index 1f3d945188a32a..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-03-11-09-39-01.bpo-39829.mlW3Su.rst +++ /dev/null @@ -1 +0,0 @@ -Removed the ``__len__()`` call when initializing a list and moved initializing to ``list_extend``. Patch by Jeremiah Pascual. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-26-15-45-57.bpo-47117.60W6GQ.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-26-15-45-57.bpo-47117.60W6GQ.rst deleted file mode 100644 index 5098ed86d07935..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-03-26-15-45-57.bpo-47117.60W6GQ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a crash if we fail to decode characters in interactive mode if the -tokenizer buffers are uninitialized. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-30-02-36-25.bpo-46775.e3Oxqf.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-30-02-36-25.bpo-46775.e3Oxqf.rst deleted file mode 100644 index da56ecd89367b8..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-03-30-02-36-25.bpo-46775.e3Oxqf.rst +++ /dev/null @@ -1,3 +0,0 @@ -Some Windows system error codes(>= 10000) are now mapped into -the correct errno and may now raise a subclass of :exc:`OSError`. -Patch by Dong-hee Na. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-31-15-37-02.bpo-47182.e_4SsC.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-31-15-37-02.bpo-47182.e_4SsC.rst deleted file mode 100644 index 08036bc680933b..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-03-31-15-37-02.bpo-47182.e_4SsC.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a crash when using a named unicode character like ``"\N{digit nine}"`` -after the main interpreter has been initialized a second time. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-04-05-11-29-21.bpo-47212.leF4pz.rst b/Misc/NEWS.d/next/Core and Builtins/2022-04-05-11-29-21.bpo-47212.leF4pz.rst deleted file mode 100644 index 8f1f6b6cfbbb89..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-04-05-11-29-21.bpo-47212.leF4pz.rst +++ /dev/null @@ -1,3 +0,0 @@ -Raise :exc:`IndentationError` instead of :exc:`SyntaxError` for a bare -``except`` with no following indent. Improve :exc:`SyntaxError` locations for -an un-parenthesized generator used as arguments. Patch by Matthieu Dartiailh. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-04-10-22-57-27.gh-issue-91421.dHhv6U.rst b/Misc/NEWS.d/next/Core and Builtins/2022-04-10-22-57-27.gh-issue-91421.dHhv6U.rst deleted file mode 100644 index 898eb0df18d01e..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-04-10-22-57-27.gh-issue-91421.dHhv6U.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a potential integer overflow in _Py_DecodeUTF8Ex. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-04-28-23-37-30.gh-issue-92036.GZJAC9.rst b/Misc/NEWS.d/next/Core and Builtins/2022-04-28-23-37-30.gh-issue-92036.GZJAC9.rst deleted file mode 100644 index 78094c5e4fea7c..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-04-28-23-37-30.gh-issue-92036.GZJAC9.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix a crash in subinterpreters related to the garbage collector. When a -subinterpreter is deleted, untrack all objects tracked by its GC. To prevent a -crash in deallocator functions expecting objects to be tracked by the GC, leak -a strong reference to these objects on purpose, so they are never deleted and -their deallocator functions are not called. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-05-01-10-58-38.gh-issue-92112.lLJemu.rst b/Misc/NEWS.d/next/Core and Builtins/2022-05-01-10-58-38.gh-issue-92112.lLJemu.rst deleted file mode 100644 index 00c938e89f4387..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-05-01-10-58-38.gh-issue-92112.lLJemu.rst +++ /dev/null @@ -1 +0,0 @@ -Fix crash triggered by an evil custom ``mro()`` on a metaclass. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-05-12-09-38-20.gh-issue-92311.VEgtts.rst b/Misc/NEWS.d/next/Core and Builtins/2022-05-12-09-38-20.gh-issue-92311.VEgtts.rst deleted file mode 100644 index b800def656cbfd..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-05-12-09-38-20.gh-issue-92311.VEgtts.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed a bug where setting ``frame.f_lineno`` to jump over a list comprehension could misbehave or crash. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-05-21-23-21-37.gh-issue-93065.5I18WC.rst b/Misc/NEWS.d/next/Core and Builtins/2022-05-21-23-21-37.gh-issue-93065.5I18WC.rst deleted file mode 100644 index ea801653f75025..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-05-21-23-21-37.gh-issue-93065.5I18WC.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix contextvars HAMT implementation to handle iteration over deep trees. - -The bug was discovered and fixed by Eli Libman. See -`MagicStack/immutables#84 `_ -for more details. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-05-22-02-37-50.gh-issue-93061.r70Imp.rst b/Misc/NEWS.d/next/Core and Builtins/2022-05-22-02-37-50.gh-issue-93061.r70Imp.rst deleted file mode 100644 index d41e59028ad570..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-05-22-02-37-50.gh-issue-93061.r70Imp.rst +++ /dev/null @@ -1 +0,0 @@ -Backward jumps after ``async for`` loops are no longer given dubious line numbers. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-05-25-04-07-22.gh-issue-91924.-UyO4q.rst b/Misc/NEWS.d/next/Core and Builtins/2022-05-25-04-07-22.gh-issue-91924.-UyO4q.rst deleted file mode 100644 index 3986ad8aa8d951..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-05-25-04-07-22.gh-issue-91924.-UyO4q.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix ``__ltrace__`` debug feature if the stdout encoding is not UTF-8. Patch -by Victor Stinner. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-06-01-17-47-40.gh-issue-93418.24dJuc.rst b/Misc/NEWS.d/next/Core and Builtins/2022-06-01-17-47-40.gh-issue-93418.24dJuc.rst deleted file mode 100644 index 74ad06bfeee7c4..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-06-01-17-47-40.gh-issue-93418.24dJuc.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed an assert where an f-string has an equal sign '=' following an -expression, but there's no trailing brace. For example, f"{i=". diff --git a/Misc/NEWS.d/next/Documentation/2017-12-10-19-13-39.bpo-13553.gQbZs4.rst b/Misc/NEWS.d/next/Documentation/2017-12-10-19-13-39.bpo-13553.gQbZs4.rst deleted file mode 100644 index 23d3c1555e3707..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2017-12-10-19-13-39.bpo-13553.gQbZs4.rst +++ /dev/null @@ -1 +0,0 @@ -Document tkinter.Tk args. diff --git a/Misc/NEWS.d/next/Documentation/2019-09-12-08-28-17.bpo-38056.6ktYkc.rst b/Misc/NEWS.d/next/Documentation/2019-09-12-08-28-17.bpo-38056.6ktYkc.rst deleted file mode 100644 index 2e6b70fd84b6d9..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-09-12-08-28-17.bpo-38056.6ktYkc.rst +++ /dev/null @@ -1 +0,0 @@ -Overhaul the :ref:`error-handlers` documentation in :mod:`codecs`. diff --git a/Misc/NEWS.d/next/Documentation/2020-07-07-22-54-51.bpo-41233.lyUJ8L.rst b/Misc/NEWS.d/next/Documentation/2020-07-07-22-54-51.bpo-41233.lyUJ8L.rst deleted file mode 100644 index ea0643aa00ee0b..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-07-07-22-54-51.bpo-41233.lyUJ8L.rst +++ /dev/null @@ -1 +0,0 @@ -Link the errnos referenced in ``Doc/library/exceptions.rst`` to their respective section in ``Doc/library/errno.rst``, and vice versa. Previously this was only done for EINTR and InterruptedError. Patch by Yan "yyyyyyyan" Orestes. diff --git a/Misc/NEWS.d/next/Documentation/2020-11-12-21-26-31.bpo-42340.apumUL.rst b/Misc/NEWS.d/next/Documentation/2020-11-12-21-26-31.bpo-42340.apumUL.rst deleted file mode 100644 index aa6857497383c6..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-11-12-21-26-31.bpo-42340.apumUL.rst +++ /dev/null @@ -1,3 +0,0 @@ -Document that in some circumstances :exc:`KeyboardInterrupt` may cause the -code to enter an inconsistent state. Provided a sample workaround to avoid -it if needed. diff --git a/Misc/NEWS.d/next/Documentation/2021-11-12-11-03-55.bpo-45790.6yuhe8.rst b/Misc/NEWS.d/next/Documentation/2021-11-12-11-03-55.bpo-45790.6yuhe8.rst deleted file mode 100644 index 41cf2cb91525f4..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2021-11-12-11-03-55.bpo-45790.6yuhe8.rst +++ /dev/null @@ -1,2 +0,0 @@ -Adjust inaccurate phrasing in :doc:`../extending/newtypes_tutorial` about the -``ob_base`` field and the macros used to access its contents. diff --git a/Misc/NEWS.d/next/Documentation/2022-01-13-16-03-15.bpo-40838.k3NVCf.rst b/Misc/NEWS.d/next/Documentation/2022-01-13-16-03-15.bpo-40838.k3NVCf.rst deleted file mode 100644 index 0f071ab64dbecc..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-01-13-16-03-15.bpo-40838.k3NVCf.rst +++ /dev/null @@ -1,2 +0,0 @@ -Document that :func:`inspect.getdoc`, :func:`inspect.getmodule`, and -:func:`inspect.getsourcefile` might return ``None``. diff --git a/Misc/NEWS.d/next/Documentation/2022-01-23-20-44-53.bpo-26792.dQ1v1W.rst b/Misc/NEWS.d/next/Documentation/2022-01-23-20-44-53.bpo-26792.dQ1v1W.rst deleted file mode 100644 index 64a39564476019..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-01-23-20-44-53.bpo-26792.dQ1v1W.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve the docstrings of :func:`runpy.run_module` and :func:`runpy.run_path`. -Original patch by Andrew Brezovsky. diff --git a/Misc/NEWS.d/next/Documentation/2022-03-08-22-10-38.bpo-46962.FIVe9I.rst b/Misc/NEWS.d/next/Documentation/2022-03-08-22-10-38.bpo-46962.FIVe9I.rst deleted file mode 100644 index f5b54013bd6720..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-03-08-22-10-38.bpo-46962.FIVe9I.rst +++ /dev/null @@ -1,4 +0,0 @@ -All docstrings in code snippets are now wrapped into :func:`PyDoc_STR` to -follow the guideline of `PEP 7's Documentation Strings paragraph -`_. Patch -by Oleg Iarygin. diff --git a/Misc/NEWS.d/next/Documentation/2022-03-28-12-29-42.bpo-47138.2B4N-k.rst b/Misc/NEWS.d/next/Documentation/2022-03-28-12-29-42.bpo-47138.2B4N-k.rst deleted file mode 100644 index e15148b73b23b4..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-03-28-12-29-42.bpo-47138.2B4N-k.rst +++ /dev/null @@ -1 +0,0 @@ -Pin Jinja to a version compatible with Sphinx version 3.2.1. diff --git a/Misc/NEWS.d/next/Documentation/2022-04-01-09-28-31.bpo-38668.j4mrqW.rst b/Misc/NEWS.d/next/Documentation/2022-04-01-09-28-31.bpo-38668.j4mrqW.rst deleted file mode 100644 index 512f0deb3543c7..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-04-01-09-28-31.bpo-38668.j4mrqW.rst +++ /dev/null @@ -1,3 +0,0 @@ -Update the introduction to documentation for :mod:`os.path` to remove -warnings that became irrelevant after the implementations of :pep:`383` and -:pep:`529`. diff --git a/Misc/NEWS.d/next/Documentation/2022-04-10-20-28-20.bpo-44347.Q1m3DM.rst b/Misc/NEWS.d/next/Documentation/2022-04-10-20-28-20.bpo-44347.Q1m3DM.rst deleted file mode 100644 index 27aa5742cd0087..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-04-10-20-28-20.bpo-44347.Q1m3DM.rst +++ /dev/null @@ -1 +0,0 @@ -Clarify the meaning of *dirs_exist_ok*, a kwarg of :func:`shutil.copytree`. diff --git a/Misc/NEWS.d/next/Documentation/2022-04-19-20-16-00.gh-issue-91547.LsNWER.rst b/Misc/NEWS.d/next/Documentation/2022-04-19-20-16-00.gh-issue-91547.LsNWER.rst deleted file mode 100644 index 95b34cb2fac1ff..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-04-19-20-16-00.gh-issue-91547.LsNWER.rst +++ /dev/null @@ -1 +0,0 @@ -Remove "Undocumented modules" page. diff --git a/Misc/NEWS.d/next/Documentation/2022-04-23-00-22-54.gh-issue-91783.N09dRR.rst b/Misc/NEWS.d/next/Documentation/2022-04-23-00-22-54.gh-issue-91783.N09dRR.rst deleted file mode 100644 index 4d6be37402079c..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-04-23-00-22-54.gh-issue-91783.N09dRR.rst +++ /dev/null @@ -1,2 +0,0 @@ -Document security issues concerning the use of the function -:meth:`shutil.unpack_archive` diff --git a/Misc/NEWS.d/next/Documentation/2022-04-24-22-09-31.gh-issue-91888.kTjJLx.rst b/Misc/NEWS.d/next/Documentation/2022-04-24-22-09-31.gh-issue-91888.kTjJLx.rst deleted file mode 100644 index 4ebca42a7fec5b..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-04-24-22-09-31.gh-issue-91888.kTjJLx.rst +++ /dev/null @@ -1 +0,0 @@ -Add a new ``gh`` role to the documentation to link to GitHub issues. diff --git a/Misc/NEWS.d/next/Documentation/2022-05-18-23-58-26.gh-issue-92240.bHvYiz.rst b/Misc/NEWS.d/next/Documentation/2022-05-18-23-58-26.gh-issue-92240.bHvYiz.rst deleted file mode 100644 index 53b2a66c9779c2..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-05-18-23-58-26.gh-issue-92240.bHvYiz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added release dates for -"What's New in Python 3.X" for 3.0, 3.1, 3.2, 3.8 and 3.10 diff --git a/Misc/NEWS.d/next/Documentation/2022-05-26-11-33-23.gh-issue-86438.kEGGmK.rst b/Misc/NEWS.d/next/Documentation/2022-05-26-11-33-23.gh-issue-86438.kEGGmK.rst deleted file mode 100644 index 75abfdd63b8b2e..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-05-26-11-33-23.gh-issue-86438.kEGGmK.rst +++ /dev/null @@ -1,3 +0,0 @@ -Clarify that :option:`-W` and :envvar:`PYTHONWARNINGS` are matched literally -and case-insensitively, rather than as regular expressions, in -:mod:`warnings`. diff --git a/Misc/NEWS.d/next/Library/2019-06-22-11-01-45.bpo-36073.ED8mB9.rst b/Misc/NEWS.d/next/Library/2019-06-22-11-01-45.bpo-36073.ED8mB9.rst deleted file mode 100644 index 6c214d8191601c..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-22-11-01-45.bpo-36073.ED8mB9.rst +++ /dev/null @@ -1,2 +0,0 @@ -Raise :exc:`~sqlite3.ProgrammingError` instead of segfaulting on recursive -usage of cursors in :mod:`sqlite3` converters. Patch by Sergey Fedoseev. diff --git a/Misc/NEWS.d/next/Library/2021-05-22-07-58-59.bpo-42627.EejtD0.rst b/Misc/NEWS.d/next/Library/2021-05-22-07-58-59.bpo-42627.EejtD0.rst deleted file mode 100644 index f165b9ced05d90..00000000000000 --- a/Misc/NEWS.d/next/Library/2021-05-22-07-58-59.bpo-42627.EejtD0.rst +++ /dev/null @@ -1 +0,0 @@ -Fix incorrect parsing of Windows registry proxy settings diff --git a/Misc/NEWS.d/next/Library/2021-07-26-10-46-49.bpo-44493.xp3CRH.rst b/Misc/NEWS.d/next/Library/2021-07-26-10-46-49.bpo-44493.xp3CRH.rst deleted file mode 100644 index 390a7222bbf55f..00000000000000 --- a/Misc/NEWS.d/next/Library/2021-07-26-10-46-49.bpo-44493.xp3CRH.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add missing terminated NUL in sockaddr_un's length - -This was potentially observable when using non-abstract AF_UNIX datagram sockets to processes written in another programming language. diff --git a/Misc/NEWS.d/next/Library/2021-09-08-16-21-03.bpo-45138.yghUrK.rst b/Misc/NEWS.d/next/Library/2021-09-08-16-21-03.bpo-45138.yghUrK.rst deleted file mode 100644 index 906ed4c4db43c8..00000000000000 --- a/Misc/NEWS.d/next/Library/2021-09-08-16-21-03.bpo-45138.yghUrK.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix a regression in the :mod:`sqlite3` trace callback where bound parameters -were not expanded in the passed statement string. The regression was introduced -in Python 3.10 by :issue:`40318`. Patch by Erlend E. Aasland. diff --git a/Misc/NEWS.d/next/Library/2022-01-09-14-23-00.bpo-28249.4dzB80.rst b/Misc/NEWS.d/next/Library/2022-01-09-14-23-00.bpo-28249.4dzB80.rst deleted file mode 100644 index b5f1312d768669..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-09-14-23-00.bpo-28249.4dzB80.rst +++ /dev/null @@ -1,2 +0,0 @@ -Set :attr:`doctest.DocTest.lineno` to ``None`` when object does not have -:attr:`__doc__`. diff --git a/Misc/NEWS.d/next/Library/2022-01-17-16-53-30.bpo-46415.6wSYg-.rst b/Misc/NEWS.d/next/Library/2022-01-17-16-53-30.bpo-46415.6wSYg-.rst deleted file mode 100644 index 016d6656041f91..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-17-16-53-30.bpo-46415.6wSYg-.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix ipaddress.ip_{address,interface,network} raising TypeError instead of -ValueError if given invalid tuple as address parameter. diff --git a/Misc/NEWS.d/next/Library/2022-02-09-23-44-27.bpo-45393.9v5Y8U.rst b/Misc/NEWS.d/next/Library/2022-02-09-23-44-27.bpo-45393.9v5Y8U.rst deleted file mode 100644 index 0a239b07d76bd1..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-09-23-44-27.bpo-45393.9v5Y8U.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix the formatting for ``await x`` and ``not x`` in the operator precedence -table when using the :func:`help` system. diff --git a/Misc/NEWS.d/next/Library/2022-02-18-20-09-29.bpo-46787.juwWc0.rst b/Misc/NEWS.d/next/Library/2022-02-18-20-09-29.bpo-46787.juwWc0.rst deleted file mode 100644 index cf167ff48115b4..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-18-20-09-29.bpo-46787.juwWc0.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :class:`concurrent.futures.ProcessPoolExecutor` exception memory leak diff --git a/Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst b/Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst deleted file mode 100644 index 1a65024e69fbdc..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst +++ /dev/null @@ -1,4 +0,0 @@ -:const:`hashlib.algorithms_available` now lists only algorithms that are -provided by activated crypto providers on OpenSSL 3.0. Legacy algorithms are -not listed unless the legacy provider has been loaded into the default -OSSL context. diff --git a/Misc/NEWS.d/next/Library/2022-03-27-12-40-16.bpo-43323.9mFPuI.rst b/Misc/NEWS.d/next/Library/2022-03-27-12-40-16.bpo-43323.9mFPuI.rst deleted file mode 100644 index 98d73101d3ee57..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-27-12-40-16.bpo-43323.9mFPuI.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix errors in the :mod:`email` module if the charset itself contains -undecodable/unencodable characters. diff --git a/Misc/NEWS.d/next/Library/2022-03-28-13-35-50.bpo-27929.j5mAmV.rst b/Misc/NEWS.d/next/Library/2022-03-28-13-35-50.bpo-27929.j5mAmV.rst deleted file mode 100644 index 4c80a10bc56844..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-28-13-35-50.bpo-27929.j5mAmV.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix :meth:`asyncio.loop.sock_connect` to only resolve names for :const:`socket.AF_INET` or -:const:`socket.AF_INET6` families. Resolution may not make sense for other families, -like :const:`socket.AF_BLUETOOTH` and :const:`socket.AF_UNIX`. diff --git a/Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst b/Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst deleted file mode 100644 index d4d02459d35de1..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst +++ /dev/null @@ -1,3 +0,0 @@ -When subprocess tries to use vfork, it now falls back to fork if vfork -returns an error. This allows use in situations where vfork isn't allowed -by the OS kernel. diff --git a/Misc/NEWS.d/next/Library/2022-04-03-19-40-09.bpo-39064.76PbIz.rst b/Misc/NEWS.d/next/Library/2022-04-03-19-40-09.bpo-39064.76PbIz.rst deleted file mode 100644 index 34d31527e332dc..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-04-03-19-40-09.bpo-39064.76PbIz.rst +++ /dev/null @@ -1,2 +0,0 @@ -:class:`zipfile.ZipFile` now raises :exc:`zipfile.BadZipFile` instead of ``ValueError`` when reading a -corrupt zip file in which the central directory offset is negative. diff --git a/Misc/NEWS.d/next/Library/2022-04-08-14-30-53.bpo-47260.TtcNxI.rst b/Misc/NEWS.d/next/Library/2022-04-08-14-30-53.bpo-47260.TtcNxI.rst deleted file mode 100644 index 300baa19c279a3..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-04-08-14-30-53.bpo-47260.TtcNxI.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix ``os.closerange()`` potentially being a no-op in a Linux seccomp -sandbox. diff --git a/Misc/NEWS.d/next/Library/2022-04-15-13-16-25.gh-issue-91581.9OGsrN.rst b/Misc/NEWS.d/next/Library/2022-04-15-13-16-25.gh-issue-91581.9OGsrN.rst deleted file mode 100644 index 1c3008f4255783..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-04-15-13-16-25.gh-issue-91581.9OGsrN.rst +++ /dev/null @@ -1,6 +0,0 @@ -Remove an unhandled error case in the C implementation of calls to -:meth:`datetime.fromtimestamp ` with no time -zone (i.e. getting a local time from an epoch timestamp). This should have no -user-facing effect other than giving a possibly more accurate error message -when called with timestamps that fall on 10000-01-01 in the local time. Patch -by Paul Ganssle. diff --git a/Misc/NEWS.d/next/Library/2022-04-15-18-38-21.gh-issue-91575.fSyAxS.rst b/Misc/NEWS.d/next/Library/2022-04-15-18-38-21.gh-issue-91575.fSyAxS.rst deleted file mode 100644 index ba046f2b4d61cf..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-04-15-18-38-21.gh-issue-91575.fSyAxS.rst +++ /dev/null @@ -1,2 +0,0 @@ -Update case-insensitive matching in the :mod:`re` module to the latest -Unicode version. diff --git a/Misc/NEWS.d/next/Library/2022-04-15-22-07-36.gh-issue-90622.0C6l8h.rst b/Misc/NEWS.d/next/Library/2022-04-15-22-07-36.gh-issue-90622.0C6l8h.rst deleted file mode 100644 index 5db0a1bbe721df..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-04-15-22-07-36.gh-issue-90622.0C6l8h.rst +++ /dev/null @@ -1,4 +0,0 @@ -Worker processes for :class:`concurrent.futures.ProcessPoolExecutor` are no -longer spawned on demand (a feature added in 3.9) when the multiprocessing -context start method is ``"fork"`` as that can lead to deadlocks in the -child processes due to a fork happening while threads are running. diff --git a/Misc/NEWS.d/next/Library/2022-04-16-05-12-13.gh-issue-91595.CocJBv.rst b/Misc/NEWS.d/next/Library/2022-04-16-05-12-13.gh-issue-91595.CocJBv.rst deleted file mode 100644 index 637079a6487a49..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-04-16-05-12-13.gh-issue-91595.CocJBv.rst +++ /dev/null @@ -1 +0,0 @@ -Fix the comparison of character and integer inside :func:`Tools.gdb.libpython.write_repr`. Patch by Yu Liu. diff --git a/Misc/NEWS.d/next/Library/2022-04-18-16-31-33.gh-issue-90568.9kiU7o.rst b/Misc/NEWS.d/next/Library/2022-04-18-16-31-33.gh-issue-90568.9kiU7o.rst deleted file mode 100644 index 4411c715830e2e..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-04-18-16-31-33.gh-issue-90568.9kiU7o.rst +++ /dev/null @@ -1,3 +0,0 @@ -Parsing ``\N`` escapes of Unicode Named Character Sequences in a -:mod:`regular expression ` raises now :exc:`re.error` instead of -``TypeError``. diff --git a/Misc/NEWS.d/next/Library/2022-04-19-04-33-39.gh-issue-91676.ceQBwh.rst b/Misc/NEWS.d/next/Library/2022-04-19-04-33-39.gh-issue-91676.ceQBwh.rst deleted file mode 100644 index dfbaef4440e0a6..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-04-19-04-33-39.gh-issue-91676.ceQBwh.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix :class:`unittest.IsolatedAsyncioTestCase` to shutdown the per test event -loop executor before returning from its ``run`` method so that a not yet -stopped or garbage collected executor state does not persist beyond the -test. diff --git a/Misc/NEWS.d/next/Library/2022-04-19-17-30-17.gh-issue-91700.MRJi6m.rst b/Misc/NEWS.d/next/Library/2022-04-19-17-30-17.gh-issue-91700.MRJi6m.rst deleted file mode 100644 index 73b106869697ba..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-04-19-17-30-17.gh-issue-91700.MRJi6m.rst +++ /dev/null @@ -1,4 +0,0 @@ -Compilation of regular expression containing a conditional expression -``(?(group)...)`` now raises an appropriate :exc:`re.error` if the group -number refers to not defined group. Previously an internal RuntimeError was -raised. diff --git a/Misc/NEWS.d/next/Library/2022-04-20-09-49-33.gh-issue-91734.4Dj4Gy.rst b/Misc/NEWS.d/next/Library/2022-04-20-09-49-33.gh-issue-91734.4Dj4Gy.rst deleted file mode 100644 index 47d9e0dea458a3..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-04-20-09-49-33.gh-issue-91734.4Dj4Gy.rst +++ /dev/null @@ -1 +0,0 @@ -Fix OSS audio support on Solaris. diff --git a/Misc/NEWS.d/next/Library/2022-04-23-03-24-00.gh-issue-91832.TyLi65.rst b/Misc/NEWS.d/next/Library/2022-04-23-03-24-00.gh-issue-91832.TyLi65.rst deleted file mode 100644 index 0ebf7735465586..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-04-23-03-24-00.gh-issue-91832.TyLi65.rst +++ /dev/null @@ -1 +0,0 @@ -Add ``required`` attribute to :class:`argparse.Action` repr output. diff --git a/Misc/NEWS.d/next/Library/2022-04-25-10-23-01.gh-issue-91810.DOHa6B.rst b/Misc/NEWS.d/next/Library/2022-04-25-10-23-01.gh-issue-91810.DOHa6B.rst deleted file mode 100644 index 0711f8466b818f..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-04-25-10-23-01.gh-issue-91810.DOHa6B.rst +++ /dev/null @@ -1,5 +0,0 @@ -:class:`~xml.etree.ElementTree.ElementTree` method -:meth:`~xml.etree.ElementTree.ElementTree.write` and function -:func:`~xml.etree.ElementTree.tostring` now use the text file's encoding -("UTF-8" if not available) instead of locale encoding in XML declaration -when ``encoding="unicode"`` is specified. diff --git a/Misc/NEWS.d/next/Library/2022-04-25-14-18-01.gh-issue-91910.kY-JR0.rst b/Misc/NEWS.d/next/Library/2022-04-25-14-18-01.gh-issue-91910.kY-JR0.rst deleted file mode 100644 index f41f357ddfcc3a..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-04-25-14-18-01.gh-issue-91910.kY-JR0.rst +++ /dev/null @@ -1 +0,0 @@ -Add missing f prefix to f-strings in error messages from the :mod:`multiprocessing` and :mod:`asyncio` modules. diff --git a/Misc/NEWS.d/next/Library/2022-04-26-00-10-06.gh-issue-91401.mddRC8.rst b/Misc/NEWS.d/next/Library/2022-04-26-00-10-06.gh-issue-91401.mddRC8.rst deleted file mode 100644 index 964a54f8935c2e..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-04-26-00-10-06.gh-issue-91401.mddRC8.rst +++ /dev/null @@ -1,5 +0,0 @@ -Provide a fail-safe way to disable :mod:`subprocess` use of ``vfork()`` via -a private ``subprocess._USE_VFORK`` attribute. While there is currently no -known need for this, if you find a need please only set it to ``False``. -File a CPython issue as to why you needed it and link to that from a -comment in your code. This attribute is documented as a footnote in 3.11. diff --git a/Misc/NEWS.d/next/Library/2022-04-26-19-01-13.bpo-47029.qkT42X.rst b/Misc/NEWS.d/next/Library/2022-04-26-19-01-13.bpo-47029.qkT42X.rst deleted file mode 100644 index cc054673338f0b..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-04-26-19-01-13.bpo-47029.qkT42X.rst +++ /dev/null @@ -1,4 +0,0 @@ -Always close the read end of the pipe used by :class:`multiprocessing.Queue` -*after* the last write of buffered data to the write end of the pipe to avoid -:exc:`BrokenPipeError` at garbage collection and at -:meth:`multiprocessing.Queue.close` calls. Patch by Géry Ogam. diff --git a/Misc/NEWS.d/next/Library/2022-04-30-10-53-10.gh-issue-92049.5SEKoh.rst b/Misc/NEWS.d/next/Library/2022-04-30-10-53-10.gh-issue-92049.5SEKoh.rst deleted file mode 100644 index cad4621c65096c..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-04-30-10-53-10.gh-issue-92049.5SEKoh.rst +++ /dev/null @@ -1,2 +0,0 @@ -Forbid pickling constants ``re._constants.SUCCESS`` etc. Previously, -pickling did not fail, but the result could not be unpickled. diff --git a/Misc/NEWS.d/next/Library/2022-05-09-09-28-02.gh-issue-92530.M4Q1RS.rst b/Misc/NEWS.d/next/Library/2022-05-09-09-28-02.gh-issue-92530.M4Q1RS.rst deleted file mode 100644 index 8bb8ca0488c962..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-05-09-09-28-02.gh-issue-92530.M4Q1RS.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix an issue that occurred after interrupting -:func:`threading.Condition.notify`. diff --git a/Misc/NEWS.d/next/Library/2022-05-11-14-34-09.gh-issue-91581.glkou2.rst b/Misc/NEWS.d/next/Library/2022-05-11-14-34-09.gh-issue-91581.glkou2.rst deleted file mode 100644 index 846f57844a6751..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-05-11-14-34-09.gh-issue-91581.glkou2.rst +++ /dev/null @@ -1,5 +0,0 @@ -:meth:`~datetime.datetime.utcfromtimestamp` no longer attempts to resolve -``fold`` in the pure Python implementation, since the fold is never 1 in UTC. -In addition to being slightly faster in the common case, this also prevents -some errors when the timestamp is close to :attr:`datetime.min -`. Patch by Paul Ganssle. diff --git a/Misc/NEWS.d/next/Library/2022-05-16-14-35-39.gh-issue-92839.owSMyo.rst b/Misc/NEWS.d/next/Library/2022-05-16-14-35-39.gh-issue-92839.owSMyo.rst deleted file mode 100644 index b425bd9c47bc91..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-05-16-14-35-39.gh-issue-92839.owSMyo.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed crash resulting from calling bisect.insort() or bisect.insort_left() with the key argument not equal to None. diff --git a/Misc/NEWS.d/next/Library/2022-05-20-15-52-43.gh-issue-93010.WF-cAc.rst b/Misc/NEWS.d/next/Library/2022-05-20-15-52-43.gh-issue-93010.WF-cAc.rst deleted file mode 100644 index 24208b5160ed52..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-05-20-15-52-43.gh-issue-93010.WF-cAc.rst +++ /dev/null @@ -1 +0,0 @@ -In a very special case, the email package tried to append the nonexistent ``InvalidHeaderError`` to the defect list. It should have been ``InvalidHeaderDefect``. diff --git a/Misc/NEWS.d/next/Library/2022-05-22-16-08-01.gh-issue-89973.jc-Q4g.rst b/Misc/NEWS.d/next/Library/2022-05-22-16-08-01.gh-issue-89973.jc-Q4g.rst deleted file mode 100644 index 7e61fd7d46a0bb..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-05-22-16-08-01.gh-issue-89973.jc-Q4g.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix :exc:`re.error` raised in :mod:`fnmatch` if the pattern contains a -character range with upper bound lower than lower bound (e.g. ``[c-a]``). -Now such ranges are interpreted as empty ranges. diff --git a/Misc/NEWS.d/next/Library/2022-05-26-23-10-55.gh-issue-93156.4XfDVN.rst b/Misc/NEWS.d/next/Library/2022-05-26-23-10-55.gh-issue-93156.4XfDVN.rst deleted file mode 100644 index 165baa08aaab14..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-05-26-23-10-55.gh-issue-93156.4XfDVN.rst +++ /dev/null @@ -1,2 +0,0 @@ -Accessing the :attr:`pathlib.PurePath.parents` sequence of an absolute path -using negative index values produced incorrect results. diff --git a/Misc/NEWS.d/next/Tests/2022-01-24-21-31-09.bpo-29890.zEG-ra.rst b/Misc/NEWS.d/next/Tests/2022-01-24-21-31-09.bpo-29890.zEG-ra.rst deleted file mode 100644 index 38a06a2f9b6be2..00000000000000 --- a/Misc/NEWS.d/next/Tests/2022-01-24-21-31-09.bpo-29890.zEG-ra.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add tests for :class:`ipaddress.IPv4Interface` and :class:`ipaddress.IPv6Interface` construction with tuple arguments. -Original patch and tests by louisom. diff --git a/Misc/NEWS.d/next/Tests/2022-03-23-22-45-51.bpo-47104._esUq8.rst b/Misc/NEWS.d/next/Tests/2022-03-23-22-45-51.bpo-47104._esUq8.rst deleted file mode 100644 index 1369bc227f5f24..00000000000000 --- a/Misc/NEWS.d/next/Tests/2022-03-23-22-45-51.bpo-47104._esUq8.rst +++ /dev/null @@ -1,2 +0,0 @@ -Rewrite :func:`asyncio.to_thread` tests to use -:class:`unittest.IsolatedAsyncioTestCase`. diff --git a/Misc/NEWS.d/next/Tests/2022-04-03-14-38-21.bpo-47205.hbbTnh.rst b/Misc/NEWS.d/next/Tests/2022-04-03-14-38-21.bpo-47205.hbbTnh.rst deleted file mode 100644 index 35fd94421326ee..00000000000000 --- a/Misc/NEWS.d/next/Tests/2022-04-03-14-38-21.bpo-47205.hbbTnh.rst +++ /dev/null @@ -1,2 +0,0 @@ -Skip test for :func:`~os.sched_getaffinity` and -:func:`~os.sched_setaffinity` error case on FreeBSD. diff --git a/Misc/NEWS.d/next/Tests/2022-04-16-17-54-05.gh-issue-91607.FnXjtW.rst b/Misc/NEWS.d/next/Tests/2022-04-16-17-54-05.gh-issue-91607.FnXjtW.rst deleted file mode 100644 index 32839a826a41ea..00000000000000 --- a/Misc/NEWS.d/next/Tests/2022-04-16-17-54-05.gh-issue-91607.FnXjtW.rst +++ /dev/null @@ -1 +0,0 @@ -Fix ``test_concurrent_futures`` to test the correct multiprocessing start method context in several cases where the test logic mixed this up. diff --git a/Misc/NEWS.d/next/Tests/2022-04-25-11-16-36.gh-issue-91904.13Uvrz.rst b/Misc/NEWS.d/next/Tests/2022-04-25-11-16-36.gh-issue-91904.13Uvrz.rst deleted file mode 100644 index 31ddfc312866b8..00000000000000 --- a/Misc/NEWS.d/next/Tests/2022-04-25-11-16-36.gh-issue-91904.13Uvrz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix initialization of :envvar:`PYTHONREGRTEST_UNICODE_GUARD` which prevented -running regression tests on non-UTF-8 locale. diff --git a/Misc/NEWS.d/next/Tests/2022-05-12-05-51-06.gh-issue-92670.7L43Z_.rst b/Misc/NEWS.d/next/Tests/2022-05-12-05-51-06.gh-issue-92670.7L43Z_.rst deleted file mode 100644 index c1349519e7c37c..00000000000000 --- a/Misc/NEWS.d/next/Tests/2022-05-12-05-51-06.gh-issue-92670.7L43Z_.rst +++ /dev/null @@ -1,3 +0,0 @@ -Skip ``test_shutil.TestCopy.test_copyfile_nonexistent_dir`` test on AIX as the test uses a trailing -slash to force the OS consider the path as a directory, but on AIX the -trailing slash has no effect and is considered as a file. diff --git a/Misc/NEWS.d/next/Tests/2022-05-25-23-07-15.gh-issue-92886.Aki63_.rst b/Misc/NEWS.d/next/Tests/2022-05-25-23-07-15.gh-issue-92886.Aki63_.rst deleted file mode 100644 index 581f6bfea24b6e..00000000000000 --- a/Misc/NEWS.d/next/Tests/2022-05-25-23-07-15.gh-issue-92886.Aki63_.rst +++ /dev/null @@ -1 +0,0 @@ -Fixing tests that fail when running with optimizations (``-O``) in ``test_imaplib.py``. diff --git a/Misc/NEWS.d/next/Tools-Demos/2022-04-20-14-26-14.gh-issue-91583.200qI0.rst b/Misc/NEWS.d/next/Tools-Demos/2022-04-20-14-26-14.gh-issue-91583.200qI0.rst deleted file mode 100644 index bdfa71100f95ae..00000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2022-04-20-14-26-14.gh-issue-91583.200qI0.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix regression in the code generated by Argument Clinic for functions with -the ``defining_class`` parameter. diff --git a/Misc/NEWS.d/next/Windows/2020-06-04-10-42-04.bpo-40859.isKSw7.rst b/Misc/NEWS.d/next/Windows/2020-06-04-10-42-04.bpo-40859.isKSw7.rst deleted file mode 100644 index ef4c727ad28661..00000000000000 --- a/Misc/NEWS.d/next/Windows/2020-06-04-10-42-04.bpo-40859.isKSw7.rst +++ /dev/null @@ -1 +0,0 @@ -Update Windows build to use xz-5.2.5 diff --git a/Misc/NEWS.d/next/Windows/2022-03-13-20-35-41.bpo-46785.Pnknyl.rst b/Misc/NEWS.d/next/Windows/2022-03-13-20-35-41.bpo-46785.Pnknyl.rst deleted file mode 100644 index 0a87abd77c8ffe..00000000000000 --- a/Misc/NEWS.d/next/Windows/2022-03-13-20-35-41.bpo-46785.Pnknyl.rst +++ /dev/null @@ -1 +0,0 @@ -Fix race condition between :func:`os.stat` and unlinking a file on Windows, by using errors codes returned by ``FindFirstFileW()`` when appropriate in ``win32_xstat_impl``. diff --git a/Misc/NEWS.d/next/Windows/2022-04-01-14-57-40.bpo-47194.IB0XL4.rst b/Misc/NEWS.d/next/Windows/2022-04-01-14-57-40.bpo-47194.IB0XL4.rst deleted file mode 100644 index 7e76add45fa953..00000000000000 --- a/Misc/NEWS.d/next/Windows/2022-04-01-14-57-40.bpo-47194.IB0XL4.rst +++ /dev/null @@ -1 +0,0 @@ -Update ``zlib`` to v1.2.12 to resolve CVE-2018-25032. diff --git a/Misc/NEWS.d/next/Windows/2022-05-19-14-01-30.gh-issue-92984.Dsxnlr.rst b/Misc/NEWS.d/next/Windows/2022-05-19-14-01-30.gh-issue-92984.Dsxnlr.rst deleted file mode 100644 index 2d3071b00b7618..00000000000000 --- a/Misc/NEWS.d/next/Windows/2022-05-19-14-01-30.gh-issue-92984.Dsxnlr.rst +++ /dev/null @@ -1 +0,0 @@ -Explicitly disable incremental linking for non-Debug builds diff --git a/README.rst b/README.rst index 215ff1e5b94cea..99db9b30c8ffff 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -This is Python version 3.10.4 +This is Python version 3.10.5 ============================= .. image:: https://travis-ci.com/python/cpython.svg?branch=master