From b44372e03c5461b6ad3d89763a9eb6cb82df07a4 Mon Sep 17 00:00:00 2001 From: Ethan Furman Date: Wed, 5 Oct 2022 15:25:55 -0700 Subject: [PATCH 1/9] gh-96865: [Enum] fix Flag to use CONFORM boundary (GH-97528) --- Lib/enum.py | 2 +- Lib/test/test_enum.py | 2 +- .../2022-09-24-18-56-23.gh-issue-96865.o9WUkW.rst | 9 +++++++++ 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-09-24-18-56-23.gh-issue-96865.o9WUkW.rst diff --git a/Lib/enum.py b/Lib/enum.py index c3aafc283719ab..a66c344dbc3db2 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -1269,7 +1269,7 @@ class FlagBoundary(StrEnum): STRICT, CONFORM, EJECT, KEEP = FlagBoundary -class Flag(Enum, boundary=STRICT): +class Flag(Enum, boundary=CONFORM): """ Support for flags """ diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index ad421f87d6d07c..f50017d916f5e3 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -2927,7 +2927,7 @@ def test_bool(self): self.assertEqual(bool(f.value), bool(f)) def test_boundary(self): - self.assertIs(enum.Flag._boundary_, STRICT) + self.assertIs(enum.Flag._boundary_, CONFORM) class Iron(Flag, boundary=STRICT): ONE = 1 TWO = 2 diff --git a/Misc/NEWS.d/next/Library/2022-09-24-18-56-23.gh-issue-96865.o9WUkW.rst b/Misc/NEWS.d/next/Library/2022-09-24-18-56-23.gh-issue-96865.o9WUkW.rst new file mode 100644 index 00000000000000..b054fdeee0785c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-09-24-18-56-23.gh-issue-96865.o9WUkW.rst @@ -0,0 +1,9 @@ +fix Flag to use boundary CONFORM + +This restores previous Flag behavior of allowing flags with non-sequential values to be combined; e.g. + + class Skip(Flag): + TWO = 2 + EIGHT = 8 + + Skip.TWO | Skip.EIGHT -> From 74ea204634f8eb4745afd5cb75c3fe7749cf38b5 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Wed, 5 Oct 2022 16:42:01 -0700 Subject: [PATCH 2/9] GH-88968: Add notes about socket ownership transfers (#97936) --- Doc/library/asyncio-eventloop.rst | 24 ++++++++++++++++++++++++ Doc/library/asyncio-stream.rst | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 6fe95687c151de..2f306b7edb8fe2 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -468,6 +468,12 @@ Opening network connections *happy_eyeballs_delay*, *interleave* and *local_addr* should be specified. + .. note:: + + The *sock* argument transfers ownership of the socket to the + transport created. To close the socket, call the transport's + :meth:`~asyncio.BaseTransport.close` method. + * *local_addr*, if given, is a ``(local_host, local_port)`` tuple used to bind the socket locally. The *local_host* and *local_port* are looked up using ``getaddrinfo()``, similarly to *host* and *port*. @@ -577,6 +583,12 @@ Opening network connections transport. If specified, *local_addr* and *remote_addr* should be omitted (must be :const:`None`). + .. note:: + + The *sock* argument transfers ownership of the socket to the + transport created. To close the socket, call the transport's + :meth:`~asyncio.BaseTransport.close` method. + See :ref:`UDP echo client protocol ` and :ref:`UDP echo server protocol ` examples. @@ -688,6 +700,12 @@ Creating network servers * *sock* can optionally be specified in order to use a preexisting socket object. If specified, *host* and *port* must not be specified. + .. note:: + + The *sock* argument transfers ownership of the socket to the + server created. To close the socket, call the server's + :meth:`~asyncio.Server.close` method. + * *backlog* is the maximum number of queued connections passed to :meth:`~socket.socket.listen` (defaults to 100). @@ -789,6 +807,12 @@ Creating network servers * *sock* is a preexisting socket object returned from :meth:`socket.accept `. + .. note:: + + The *sock* argument transfers ownership of the socket to the + transport created. To close the socket, call the transport's + :meth:`~asyncio.BaseTransport.close` method. + * *ssl* can be set to an :class:`~ssl.SSLContext` to enable SSL over the accepted connections. diff --git a/Doc/library/asyncio-stream.rst b/Doc/library/asyncio-stream.rst index 9b468670a2521e..ce88d70d6607d9 100644 --- a/Doc/library/asyncio-stream.rst +++ b/Doc/library/asyncio-stream.rst @@ -67,6 +67,12 @@ and work with streams: The rest of the arguments are passed directly to :meth:`loop.create_connection`. + .. note:: + + The *sock* argument transfers ownership of the socket to the + :class:`StreamWriter` created. To close the socket, call its + :meth:`~asyncio.StreamWriter.close` method. + .. versionchanged:: 3.7 Added the *ssl_handshake_timeout* parameter. @@ -103,6 +109,12 @@ and work with streams: The rest of the arguments are passed directly to :meth:`loop.create_server`. + .. note:: + + The *sock* argument transfers ownership of the socket to the + server created. To close the socket, call the server's + :meth:`~asyncio.Server.close` method. + .. versionchanged:: 3.7 Added the *ssl_handshake_timeout* and *start_serving* parameters. @@ -123,6 +135,12 @@ and work with streams: See also the documentation of :meth:`loop.create_unix_connection`. + .. note:: + + The *sock* argument transfers ownership of the socket to the + :class:`StreamWriter` created. To close the socket, call its + :meth:`~asyncio.StreamWriter.close` method. + .. availability:: Unix. .. versionchanged:: 3.7 @@ -143,6 +161,12 @@ and work with streams: See also the documentation of :meth:`loop.create_unix_server`. + .. note:: + + The *sock* argument transfers ownership of the socket to the + server created. To close the socket, call the server's + :meth:`~asyncio.Server.close` method. + .. availability:: Unix. .. versionchanged:: 3.7 From 0d68879104dfb392d31e52e25dcb0661801a0249 Mon Sep 17 00:00:00 2001 From: 180909 <734461790@qq.com> Date: Thu, 6 Oct 2022 07:57:42 +0800 Subject: [PATCH 3/9] gh-95691: Doc BufferedWriter and BufferedReader (#95703) --- Doc/library/io.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/io.rst b/Doc/library/io.rst index 7ec990c3212a3e..8fd6b3537019aa 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -272,7 +272,7 @@ to provide an interface to files in the machine's file system. The :class:`BufferedIOBase` ABC extends :class:`IOBase`. It deals with buffering on a raw binary stream (:class:`RawIOBase`). Its subclasses, :class:`BufferedWriter`, :class:`BufferedReader`, and :class:`BufferedRWPair` -buffer raw binary streams that are readable, writable, and both readable and writable, +buffer raw binary streams that are writable, readable, and both readable and writable, respectively. :class:`BufferedRandom` provides a buffered interface to seekable streams. Another :class:`BufferedIOBase` subclass, :class:`BytesIO`, is a stream of in-memory bytes. From e39ae6bef2c357a88e232dcab2e4b4c0f367544b Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Thu, 6 Oct 2022 15:16:16 +0300 Subject: [PATCH 4/9] gh-94808: Cover `PyObject_PyBytes` case with custom `__bytes__` method (#96610) Co-authored-by: Jelle Zijlstra --- Lib/test/test_long.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py index d092e0176c2616..b6407b5a7c881e 100644 --- a/Lib/test/test_long.py +++ b/Lib/test/test_long.py @@ -1518,6 +1518,22 @@ def __init__(self, value): self.assertEqual(i, 1) self.assertEqual(getattr(i, 'foo', 'none'), 'bar') + class ValidBytes: + def __bytes__(self): + return b'\x01' + class InvalidBytes: + def __bytes__(self): + return 'abc' + class MissingBytes: ... + class RaisingBytes: + def __bytes__(self): + 1 / 0 + + self.assertEqual(int.from_bytes(ValidBytes()), 1) + self.assertRaises(TypeError, int.from_bytes, InvalidBytes()) + self.assertRaises(TypeError, int.from_bytes, MissingBytes()) + self.assertRaises(ZeroDivisionError, int.from_bytes, RaisingBytes()) + @support.cpython_only def test_from_bytes_small(self): # bpo-46361 From e63d7dae90d15957303688285daeebc2e931e04b Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Thu, 6 Oct 2022 18:20:22 +0300 Subject: [PATCH 5/9] gh-94808: Cover `PyUnicode_Count` in CAPI (#96929) --- Lib/test/test_unicode.py | 38 +++++++++++++++++++++++++++++++++++++ Modules/_testcapi/unicode.c | 21 ++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index 63bccb72e04646..30faaaf83bec96 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -2945,6 +2945,44 @@ def test_asutf8andsize(self): self.assertEqual(unicode_asutf8andsize(nonbmp), (b'\xf4\x8f\xbf\xbf', 4)) self.assertRaises(UnicodeEncodeError, unicode_asutf8andsize, 'a\ud800b\udfffc') + # Test PyUnicode_Count() + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_count(self): + from _testcapi import unicode_count + + st = 'abcabd' + self.assertEqual(unicode_count(st, 'a', 0, len(st)), 2) + self.assertEqual(unicode_count(st, 'ab', 0, len(st)), 2) + self.assertEqual(unicode_count(st, 'abc', 0, len(st)), 1) + self.assertEqual(unicode_count(st, 'а', 0, len(st)), 0) # cyrillic "a" + # start < end + self.assertEqual(unicode_count(st, 'a', 3, len(st)), 1) + self.assertEqual(unicode_count(st, 'a', 4, len(st)), 0) + self.assertEqual(unicode_count(st, 'a', 0, sys.maxsize), 2) + # start >= end + self.assertEqual(unicode_count(st, 'abc', 0, 0), 0) + self.assertEqual(unicode_count(st, 'a', 3, 2), 0) + self.assertEqual(unicode_count(st, 'a', sys.maxsize, 5), 0) + # negative + self.assertEqual(unicode_count(st, 'ab', -len(st), -1), 2) + self.assertEqual(unicode_count(st, 'a', -len(st), -3), 1) + # wrong args + self.assertRaises(TypeError, unicode_count, 'a', 'a') + self.assertRaises(TypeError, unicode_count, 'a', 'a', 1) + self.assertRaises(TypeError, unicode_count, 1, 'a', 0, 1) + self.assertRaises(TypeError, unicode_count, 'a', 1, 0, 1) + # empty string + self.assertEqual(unicode_count('abc', '', 0, 3), 4) + self.assertEqual(unicode_count('abc', '', 1, 3), 3) + self.assertEqual(unicode_count('', '', 0, 1), 1) + self.assertEqual(unicode_count('', 'a', 0, 1), 0) + # different unicode kinds + for uni in "\xa1", "\u8000\u8080", "\ud800\udc02", "\U0001f100\U0001f1f1": + for ch in uni: + self.assertEqual(unicode_count(uni, ch, 0, len(uni)), 1) + self.assertEqual(unicode_count(st, ch, 0, len(st)), 0) + # Test PyUnicode_FindChar() @support.cpython_only @unittest.skipIf(_testcapi is None, 'need _testcapi module') diff --git a/Modules/_testcapi/unicode.c b/Modules/_testcapi/unicode.c index d0f1e2abdc8259..d5c4a9e5b95ec6 100644 --- a/Modules/_testcapi/unicode.c +++ b/Modules/_testcapi/unicode.c @@ -223,6 +223,26 @@ unicode_asutf8andsize(PyObject *self, PyObject *args) return Py_BuildValue("(Nn)", result, utf8_len); } +static PyObject * +unicode_count(PyObject *self, PyObject *args) +{ + PyObject *str; + PyObject *substr; + Py_ssize_t result; + Py_ssize_t start, end; + + if (!PyArg_ParseTuple(args, "UUnn:unicode_count", &str, &substr, + &start, &end)) { + return NULL; + } + + result = PyUnicode_Count(str, substr, start, end); + if (result == -1) + return NULL; + else + return PyLong_FromSsize_t(result); +} + static PyObject * unicode_findchar(PyObject *self, PyObject *args) { @@ -696,6 +716,7 @@ static PyMethodDef TestMethods[] = { {"unicode_asucs4", unicode_asucs4, METH_VARARGS}, {"unicode_asutf8", unicode_asutf8, METH_VARARGS}, {"unicode_asutf8andsize", unicode_asutf8andsize, METH_VARARGS}, + {"unicode_count", unicode_count, METH_VARARGS}, {"unicode_findchar", unicode_findchar, METH_VARARGS}, {"unicode_copycharacters", unicode_copycharacters, METH_VARARGS}, {NULL}, From 6d0a0191a4e5477bd843e62c24d7f3bcad4fd5fc Mon Sep 17 00:00:00 2001 From: Ned Deily Date: Thu, 6 Oct 2022 09:11:47 -0700 Subject: [PATCH 6/9] gh-97897: Prevent os.mkfifo and os.mknod segfaults with macOS 13 SDK (GH-97944) The macOS 13 SDK includes support for the `mkfifoat` and `mknodat` system calls. Using the `dir_fd` option with either `os.mkfifo` or `os.mknod` could result in a segfault if cpython is built with the macOS 13 SDK but run on an earlier version of macOS. Prevent this by adding runtime support for detection of these system calls ("weaklinking") as is done for other newer syscalls on macOS. --- Lib/test/test_posix.py | 22 +++++++ ...2-10-05-15-26-58.gh-issue-97897.Rf-C6u.rst | 6 ++ Modules/posixmodule.c | 60 ++++++++++++++++--- 3 files changed, 80 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/macOS/2022-10-05-15-26-58.gh-issue-97897.Rf-C6u.rst diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index ae25ef55885dd6..e643d8e5a4ce63 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -2090,6 +2090,28 @@ def test_mkdir(self): with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"): os.mkdir("dir", dir_fd=0) + def test_mkfifo(self): + self._verify_available("HAVE_MKFIFOAT") + if self.mac_ver >= (13, 0): + self.assertIn("HAVE_MKFIFOAT", posix._have_functions) + + else: + self.assertNotIn("HAVE_MKFIFOAT", posix._have_functions) + + with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"): + os.mkfifo("path", dir_fd=0) + + def test_mknod(self): + self._verify_available("HAVE_MKNODAT") + if self.mac_ver >= (13, 0): + self.assertIn("HAVE_MKNODAT", posix._have_functions) + + else: + self.assertNotIn("HAVE_MKNODAT", posix._have_functions) + + with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"): + os.mknod("path", dir_fd=0) + def test_rename_replace(self): self._verify_available("HAVE_RENAMEAT") if self.mac_ver >= (10, 10): diff --git a/Misc/NEWS.d/next/macOS/2022-10-05-15-26-58.gh-issue-97897.Rf-C6u.rst b/Misc/NEWS.d/next/macOS/2022-10-05-15-26-58.gh-issue-97897.Rf-C6u.rst new file mode 100644 index 00000000000000..0d21e98b37c5a3 --- /dev/null +++ b/Misc/NEWS.d/next/macOS/2022-10-05-15-26-58.gh-issue-97897.Rf-C6u.rst @@ -0,0 +1,6 @@ +The macOS 13 SDK includes support for the ``mkfifoat`` and ``mknodat`` system calls. +Using the ``dir_fd`` option with either :func:`os.mkfifo` or :func:`os.mknod` could result in a +segfault if cpython is built with the macOS 13 SDK but run on an earlier +version of macOS. Prevent this by adding runtime support for detection of +these system calls ("weaklinking") as is done for other newer syscalls on +macOS. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 3810bc87c1fbab..cbdc259737583c 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -91,6 +91,8 @@ # define HAVE_FUTIMENS_RUNTIME __builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) # define HAVE_UTIMENSAT_RUNTIME __builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) # define HAVE_PWRITEV_RUNTIME __builtin_available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *) +# define HAVE_MKFIFOAT_RUNTIME __builtin_available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *) +# define HAVE_MKNODAT_RUNTIME __builtin_available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *) # define HAVE_POSIX_SPAWN_SETSID_RUNTIME __builtin_available(macOS 10.15, *) @@ -175,6 +177,8 @@ # define HAVE_FUTIMENS_RUNTIME 1 # define HAVE_UTIMENSAT_RUNTIME 1 # define HAVE_PWRITEV_RUNTIME 1 +# define HAVE_MKFIFOAT_RUNTIME 1 +# define HAVE_MKNODAT_RUNTIME 1 #endif @@ -10619,18 +10623,35 @@ os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd) { int result; int async_err = 0; +#ifdef HAVE_MKFIFOAT + int mkfifoat_unavailable = 0; +#endif do { Py_BEGIN_ALLOW_THREADS #ifdef HAVE_MKFIFOAT - if (dir_fd != DEFAULT_DIR_FD) - result = mkfifoat(dir_fd, path->narrow, mode); - else + if (dir_fd != DEFAULT_DIR_FD) { + if (HAVE_MKFIFOAT_RUNTIME) { + result = mkfifoat(dir_fd, path->narrow, mode); + + } else { + mkfifoat_unavailable = 1; + result = 0; + } + } else #endif result = mkfifo(path->narrow, mode); Py_END_ALLOW_THREADS } while (result != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + +#ifdef HAVE_MKFIFOAT + if (mkfifoat_unavailable) { + argument_unavailable_error(NULL, "dir_fd"); + return NULL; + } +#endif + if (result != 0) return (!async_err) ? posix_error() : NULL; @@ -10671,18 +10692,33 @@ os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device, { int result; int async_err = 0; +#ifdef HAVE_MKNODAT + int mknodat_unavailable = 0; +#endif do { Py_BEGIN_ALLOW_THREADS #ifdef HAVE_MKNODAT - if (dir_fd != DEFAULT_DIR_FD) - result = mknodat(dir_fd, path->narrow, mode, device); - else + if (dir_fd != DEFAULT_DIR_FD) { + if (HAVE_MKNODAT_RUNTIME) { + result = mknodat(dir_fd, path->narrow, mode, device); + + } else { + mknodat_unavailable = 1; + result = 0; + } + } else #endif result = mknod(path->narrow, mode, device); Py_END_ALLOW_THREADS } while (result != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); +#ifdef HAVE_MKNODAT + if (mknodat_unavailable) { + argument_unavailable_error(NULL, "dir_fd"); + return NULL; + } +#endif if (result != 0) return (!async_err) ? posix_error() : NULL; @@ -15525,6 +15561,14 @@ PROBE(probe_fdopendir, HAVE_FDOPENDIR_RUNTIME) PROBE(probe_mkdirat, HAVE_MKDIRAT_RUNTIME) #endif +#ifdef HAVE_MKFIFOAT +PROBE(probe_mkfifoat, HAVE_MKFIFOAT_RUNTIME) +#endif + +#ifdef HAVE_MKNODAT +PROBE(probe_mknodat, HAVE_MKNODAT_RUNTIME) +#endif + #ifdef HAVE_RENAMEAT PROBE(probe_renameat, HAVE_RENAMEAT_RUNTIME) #endif @@ -15658,11 +15702,11 @@ static const struct have_function { #endif #ifdef HAVE_MKFIFOAT - { "HAVE_MKFIFOAT", NULL }, + { "HAVE_MKFIFOAT", probe_mkfifoat }, #endif #ifdef HAVE_MKNODAT - { "HAVE_MKNODAT", NULL }, + { "HAVE_MKNODAT", probe_mknodat }, #endif #ifdef HAVE_OPENAT From cd0fde27f9657266a0fb5782a5234678f2cf4662 Mon Sep 17 00:00:00 2001 From: 180909 <734461790@qq.com> Date: Fri, 7 Oct 2022 00:52:21 +0800 Subject: [PATCH 7/9] gh-95986: Fix the example using match keyword (#95989) --- Doc/whatsnew/3.10.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index db8d9281b1f2ed..428a19453db522 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -669,6 +669,7 @@ Several other key features: GREEN = 1 BLUE = 2 + color = Color.GREEN match color: case Color.RED: print("I see red!") From f612565bd32d4ab0945798da775eea070f08b6fe Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Thu, 6 Oct 2022 18:11:37 +0100 Subject: [PATCH 8/9] gh-93738: Disallow pre-v3 syntax in the C domain (#97962) Also, disable using invalid sphinx-lint 0.6.2. --- Doc/conf.py | 25 ------------------------- Doc/extending/newtypes.rst | 6 +++--- Doc/extending/newtypes_tutorial.rst | 2 +- Doc/howto/isolating-extensions.rst | 2 +- Doc/requirements.txt | 5 ++++- Doc/whatsnew/2.2.rst | 2 +- Doc/whatsnew/2.5.rst | 2 +- 7 files changed, 11 insertions(+), 33 deletions(-) diff --git a/Doc/conf.py b/Doc/conf.py index 909f992d9d821a..be1c9fff51a277 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -239,28 +239,3 @@ # Relative filename of the data files refcount_file = 'data/refcounts.dat' stable_abi_file = 'data/stable_abi.dat' - -# Sphinx 2 and Sphinx 3 compatibility -# ----------------------------------- - -# bpo-40204: Allow Sphinx 2 syntax in the C domain -c_allow_pre_v3 = True - -# bpo-40204: Disable warnings on Sphinx 2 syntax of the C domain since the -# documentation is built with -W (warnings treated as errors). -c_warn_on_allowed_pre_v3 = False - -# Fix '!' not working with C domain when pre_v3 is enabled -import sphinx - -if sphinx.version_info[:2] < (5, 3): - from sphinx.domains.c import CXRefRole - - original_run = CXRefRole.run - - def new_run(self): - if self.disabled: - return super(CXRefRole, self).run() - return original_run(self) - - CXRefRole.run = new_run diff --git a/Doc/extending/newtypes.rst b/Doc/extending/newtypes.rst index a076eae534b91e..3de849ade78888 100644 --- a/Doc/extending/newtypes.rst +++ b/Doc/extending/newtypes.rst @@ -208,7 +208,7 @@ a special case, for which the new value passed to the handler is ``NULL``. Python supports two pairs of attribute handlers; a type that supports attributes only needs to implement the functions for one pair. The difference is that one pair takes the name of the attribute as a :c:expr:`char\*`, while the other -accepts a :c:type:`PyObject\*`. Each type can use whichever pair makes more +accepts a :c:expr:`PyObject*`. Each type can use whichever pair makes more sense for the implementation's convenience. :: getattrfunc tp_getattr; /* char * version */ @@ -219,7 +219,7 @@ sense for the implementation's convenience. :: If accessing attributes of an object is always a simple operation (this will be explained shortly), there are generic implementations which can be used to -provide the :c:type:`PyObject\*` version of the attribute management functions. +provide the :c:expr:`PyObject*` version of the attribute management functions. The actual need for type-specific attribute handlers almost completely disappeared starting with Python 2.2, though there are many examples which have not been updated to use some of the new generic mechanism that is available. @@ -341,7 +341,7 @@ Type-specific Attribute Management For simplicity, only the :c:expr:`char\*` version will be demonstrated here; the type of the name parameter is the only difference between the :c:expr:`char\*` -and :c:type:`PyObject\*` flavors of the interface. This example effectively does +and :c:expr:`PyObject*` flavors of the interface. This example effectively does the same thing as the generic example above, but does not use the generic support added in Python 2.2. It explains how the handler functions are called, so that if you do need to extend their functionality, you'll understand diff --git a/Doc/extending/newtypes_tutorial.rst b/Doc/extending/newtypes_tutorial.rst index 34c25d1f6f199c..5d4a3f06dd5402 100644 --- a/Doc/extending/newtypes_tutorial.rst +++ b/Doc/extending/newtypes_tutorial.rst @@ -24,7 +24,7 @@ The Basics ========== The :term:`CPython` runtime sees all Python objects as variables of type -:c:type:`PyObject\*`, which serves as a "base type" for all Python objects. +:c:expr:`PyObject*`, which serves as a "base type" for all Python objects. The :c:type:`PyObject` structure itself only contains the object's :term:`reference count` and a pointer to the object's "type object". This is where the action is; the type object determines which (C) functions diff --git a/Doc/howto/isolating-extensions.rst b/Doc/howto/isolating-extensions.rst index 8ee7e5e28479a5..2657b4ec6aaf9f 100644 --- a/Doc/howto/isolating-extensions.rst +++ b/Doc/howto/isolating-extensions.rst @@ -411,7 +411,7 @@ that subclass, which may be defined in different module than yours. pass For a method to get its "defining class", it must use the -:c:data:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS` +:data:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS` :c:type:`calling convention ` and the corresponding :c:type:`PyCMethod` signature:: diff --git a/Doc/requirements.txt b/Doc/requirements.txt index f8a7f9db144c21..be058733fcf4d7 100644 --- a/Doc/requirements.txt +++ b/Doc/requirements.txt @@ -7,7 +7,10 @@ sphinx==4.5.0 blurb -sphinx-lint<1 +# sphinx-lint 0.6.2 yields many default role errors due to the new regular +# expression used for default role detection, so we don't use the version +# until the errors are fixed. +sphinx-lint<1,!=0.6.2 # The theme used by the documentation is stored separately, so we need # to install that as well. diff --git a/Doc/whatsnew/2.2.rst b/Doc/whatsnew/2.2.rst index bfb2aacbc07747..39997661bb96c4 100644 --- a/Doc/whatsnew/2.2.rst +++ b/Doc/whatsnew/2.2.rst @@ -1102,7 +1102,7 @@ code, none of the changes described here will affect you very much. * A different argument parsing function, :c:func:`PyArg_UnpackTuple`, has been added that's simpler and presumably faster. Instead of specifying a format string, the caller simply gives the minimum and maximum number of arguments - expected, and a set of pointers to :c:type:`PyObject\*` variables that will be + expected, and a set of pointers to :c:expr:`PyObject*` variables that will be filled in with argument values. * Two new flags :const:`METH_NOARGS` and :const:`METH_O` are available in method diff --git a/Doc/whatsnew/2.5.rst b/Doc/whatsnew/2.5.rst index 0aca2fe697ccdb..dcfaef6ed29494 100644 --- a/Doc/whatsnew/2.5.rst +++ b/Doc/whatsnew/2.5.rst @@ -1725,7 +1725,7 @@ attribute of the function object to change this:: ``ctypes.pythonapi`` object. This object does *not* release the global interpreter lock before calling a function, because the lock must be held when calling into the interpreter's code. There's a :class:`py_object()` type -constructor that will create a :c:type:`PyObject \*` pointer. A simple usage:: +constructor that will create a :c:expr:`PyObject *` pointer. A simple usage:: import ctypes From e2e6b95c0342247ed1a761b6e149ac579a8722dd Mon Sep 17 00:00:00 2001 From: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> Date: Thu, 6 Oct 2022 22:48:19 +0530 Subject: [PATCH 9/9] GH-88050: fix race in closing subprocess pipe in asyncio (#97951) Check for None when iterating over `self._pipes.values()`. --- Lib/asyncio/base_subprocess.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Lib/asyncio/base_subprocess.py b/Lib/asyncio/base_subprocess.py index c2ca4a2792f666..e15bb4141fc02a 100644 --- a/Lib/asyncio/base_subprocess.py +++ b/Lib/asyncio/base_subprocess.py @@ -216,7 +216,9 @@ def _process_exited(self, returncode): self._proc.returncode = returncode self._call(self._protocol.process_exited) for p in self._pipes.values(): - p.pipe.close() + if p is not None: + p.pipe.close() + self._try_finish() async def _wait(self):