Skip to content

Commit 7938d6f

Browse files
committed
Merge branch 'main' into dictwatch
* main: pythonGH-88050: fix race in closing subprocess pipe in asyncio (python#97951) pythongh-93738: Disallow pre-v3 syntax in the C domain (python#97962) pythongh-95986: Fix the example using match keyword (python#95989) pythongh-97897: Prevent os.mkfifo and os.mknod segfaults with macOS 13 SDK (pythonGH-97944) pythongh-94808: Cover `PyUnicode_Count` in CAPI (python#96929) pythongh-94808: Cover `PyObject_PyBytes` case with custom `__bytes__` method (python#96610) pythongh-95691: Doc BufferedWriter and BufferedReader (python#95703) pythonGH-88968: Add notes about socket ownership transfers (python#97936) pythongh-96865: [Enum] fix Flag to use CONFORM boundary (pythonGH-97528)
2 parents 7dcf9b0 + e2e6b95 commit 7938d6f

21 files changed

+230
-45
lines changed

Doc/conf.py

-25
Original file line numberDiff line numberDiff line change
@@ -239,28 +239,3 @@
239239
# Relative filename of the data files
240240
refcount_file = 'data/refcounts.dat'
241241
stable_abi_file = 'data/stable_abi.dat'
242-
243-
# Sphinx 2 and Sphinx 3 compatibility
244-
# -----------------------------------
245-
246-
# bpo-40204: Allow Sphinx 2 syntax in the C domain
247-
c_allow_pre_v3 = True
248-
249-
# bpo-40204: Disable warnings on Sphinx 2 syntax of the C domain since the
250-
# documentation is built with -W (warnings treated as errors).
251-
c_warn_on_allowed_pre_v3 = False
252-
253-
# Fix '!' not working with C domain when pre_v3 is enabled
254-
import sphinx
255-
256-
if sphinx.version_info[:2] < (5, 3):
257-
from sphinx.domains.c import CXRefRole
258-
259-
original_run = CXRefRole.run
260-
261-
def new_run(self):
262-
if self.disabled:
263-
return super(CXRefRole, self).run()
264-
return original_run(self)
265-
266-
CXRefRole.run = new_run

Doc/extending/newtypes.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ a special case, for which the new value passed to the handler is ``NULL``.
208208
Python supports two pairs of attribute handlers; a type that supports attributes
209209
only needs to implement the functions for one pair. The difference is that one
210210
pair takes the name of the attribute as a :c:expr:`char\*`, while the other
211-
accepts a :c:type:`PyObject\*`. Each type can use whichever pair makes more
211+
accepts a :c:expr:`PyObject*`. Each type can use whichever pair makes more
212212
sense for the implementation's convenience. ::
213213

214214
getattrfunc tp_getattr; /* char * version */
@@ -219,7 +219,7 @@ sense for the implementation's convenience. ::
219219

220220
If accessing attributes of an object is always a simple operation (this will be
221221
explained shortly), there are generic implementations which can be used to
222-
provide the :c:type:`PyObject\*` version of the attribute management functions.
222+
provide the :c:expr:`PyObject*` version of the attribute management functions.
223223
The actual need for type-specific attribute handlers almost completely
224224
disappeared starting with Python 2.2, though there are many examples which have
225225
not been updated to use some of the new generic mechanism that is available.
@@ -341,7 +341,7 @@ Type-specific Attribute Management
341341

342342
For simplicity, only the :c:expr:`char\*` version will be demonstrated here; the
343343
type of the name parameter is the only difference between the :c:expr:`char\*`
344-
and :c:type:`PyObject\*` flavors of the interface. This example effectively does
344+
and :c:expr:`PyObject*` flavors of the interface. This example effectively does
345345
the same thing as the generic example above, but does not use the generic
346346
support added in Python 2.2. It explains how the handler functions are
347347
called, so that if you do need to extend their functionality, you'll understand

Doc/extending/newtypes_tutorial.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ The Basics
2424
==========
2525

2626
The :term:`CPython` runtime sees all Python objects as variables of type
27-
:c:type:`PyObject\*`, which serves as a "base type" for all Python objects.
27+
:c:expr:`PyObject*`, which serves as a "base type" for all Python objects.
2828
The :c:type:`PyObject` structure itself only contains the object's
2929
:term:`reference count` and a pointer to the object's "type object".
3030
This is where the action is; the type object determines which (C) functions

Doc/howto/isolating-extensions.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ that subclass, which may be defined in different module than yours.
411411
pass
412412
413413
For a method to get its "defining class", it must use the
414-
:c:data:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS`
414+
:data:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS`
415415
:c:type:`calling convention <PyMethodDef>`
416416
and the corresponding :c:type:`PyCMethod` signature::
417417

Doc/library/asyncio-eventloop.rst

+24
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,12 @@ Opening network connections
468468
*happy_eyeballs_delay*, *interleave*
469469
and *local_addr* should be specified.
470470

471+
.. note::
472+
473+
The *sock* argument transfers ownership of the socket to the
474+
transport created. To close the socket, call the transport's
475+
:meth:`~asyncio.BaseTransport.close` method.
476+
471477
* *local_addr*, if given, is a ``(local_host, local_port)`` tuple used
472478
to bind the socket locally. The *local_host* and *local_port*
473479
are looked up using ``getaddrinfo()``, similarly to *host* and *port*.
@@ -577,6 +583,12 @@ Opening network connections
577583
transport. If specified, *local_addr* and *remote_addr* should be omitted
578584
(must be :const:`None`).
579585

586+
.. note::
587+
588+
The *sock* argument transfers ownership of the socket to the
589+
transport created. To close the socket, call the transport's
590+
:meth:`~asyncio.BaseTransport.close` method.
591+
580592
See :ref:`UDP echo client protocol <asyncio-udp-echo-client-protocol>` and
581593
:ref:`UDP echo server protocol <asyncio-udp-echo-server-protocol>` examples.
582594

@@ -688,6 +700,12 @@ Creating network servers
688700
* *sock* can optionally be specified in order to use a preexisting
689701
socket object. If specified, *host* and *port* must not be specified.
690702

703+
.. note::
704+
705+
The *sock* argument transfers ownership of the socket to the
706+
server created. To close the socket, call the server's
707+
:meth:`~asyncio.Server.close` method.
708+
691709
* *backlog* is the maximum number of queued connections passed to
692710
:meth:`~socket.socket.listen` (defaults to 100).
693711

@@ -789,6 +807,12 @@ Creating network servers
789807
* *sock* is a preexisting socket object returned from
790808
:meth:`socket.accept <socket.socket.accept>`.
791809

810+
.. note::
811+
812+
The *sock* argument transfers ownership of the socket to the
813+
transport created. To close the socket, call the transport's
814+
:meth:`~asyncio.BaseTransport.close` method.
815+
792816
* *ssl* can be set to an :class:`~ssl.SSLContext` to enable SSL over
793817
the accepted connections.
794818

Doc/library/asyncio-stream.rst

+24
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ and work with streams:
6767
The rest of the arguments are passed directly to
6868
:meth:`loop.create_connection`.
6969

70+
.. note::
71+
72+
The *sock* argument transfers ownership of the socket to the
73+
:class:`StreamWriter` created. To close the socket, call its
74+
:meth:`~asyncio.StreamWriter.close` method.
75+
7076
.. versionchanged:: 3.7
7177
Added the *ssl_handshake_timeout* parameter.
7278

@@ -103,6 +109,12 @@ and work with streams:
103109
The rest of the arguments are passed directly to
104110
:meth:`loop.create_server`.
105111

112+
.. note::
113+
114+
The *sock* argument transfers ownership of the socket to the
115+
server created. To close the socket, call the server's
116+
:meth:`~asyncio.Server.close` method.
117+
106118
.. versionchanged:: 3.7
107119
Added the *ssl_handshake_timeout* and *start_serving* parameters.
108120

@@ -123,6 +135,12 @@ and work with streams:
123135

124136
See also the documentation of :meth:`loop.create_unix_connection`.
125137

138+
.. note::
139+
140+
The *sock* argument transfers ownership of the socket to the
141+
:class:`StreamWriter` created. To close the socket, call its
142+
:meth:`~asyncio.StreamWriter.close` method.
143+
126144
.. availability:: Unix.
127145

128146
.. versionchanged:: 3.7
@@ -143,6 +161,12 @@ and work with streams:
143161

144162
See also the documentation of :meth:`loop.create_unix_server`.
145163

164+
.. note::
165+
166+
The *sock* argument transfers ownership of the socket to the
167+
server created. To close the socket, call the server's
168+
:meth:`~asyncio.Server.close` method.
169+
146170
.. availability:: Unix.
147171

148172
.. versionchanged:: 3.7

Doc/library/io.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ to provide an interface to files in the machine's file system.
272272
The :class:`BufferedIOBase` ABC extends :class:`IOBase`. It deals with
273273
buffering on a raw binary stream (:class:`RawIOBase`). Its subclasses,
274274
:class:`BufferedWriter`, :class:`BufferedReader`, and :class:`BufferedRWPair`
275-
buffer raw binary streams that are readable, writable, and both readable and writable,
275+
buffer raw binary streams that are writable, readable, and both readable and writable,
276276
respectively. :class:`BufferedRandom` provides a buffered interface to seekable streams.
277277
Another :class:`BufferedIOBase` subclass, :class:`BytesIO`, is a stream of
278278
in-memory bytes.

Doc/requirements.txt

+4-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ sphinx==4.5.0
77

88
blurb
99

10-
sphinx-lint<1
10+
# sphinx-lint 0.6.2 yields many default role errors due to the new regular
11+
# expression used for default role detection, so we don't use the version
12+
# until the errors are fixed.
13+
sphinx-lint<1,!=0.6.2
1114

1215
# The theme used by the documentation is stored separately, so we need
1316
# to install that as well.

Doc/whatsnew/2.2.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -1102,7 +1102,7 @@ code, none of the changes described here will affect you very much.
11021102
* A different argument parsing function, :c:func:`PyArg_UnpackTuple`, has been
11031103
added that's simpler and presumably faster. Instead of specifying a format
11041104
string, the caller simply gives the minimum and maximum number of arguments
1105-
expected, and a set of pointers to :c:type:`PyObject\*` variables that will be
1105+
expected, and a set of pointers to :c:expr:`PyObject*` variables that will be
11061106
filled in with argument values.
11071107

11081108
* Two new flags :const:`METH_NOARGS` and :const:`METH_O` are available in method

Doc/whatsnew/2.5.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -1725,7 +1725,7 @@ attribute of the function object to change this::
17251725
``ctypes.pythonapi`` object. This object does *not* release the global
17261726
interpreter lock before calling a function, because the lock must be held when
17271727
calling into the interpreter's code. There's a :class:`py_object()` type
1728-
constructor that will create a :c:type:`PyObject \*` pointer. A simple usage::
1728+
constructor that will create a :c:expr:`PyObject *` pointer. A simple usage::
17291729

17301730
import ctypes
17311731

Doc/whatsnew/3.10.rst

+1
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,7 @@ Several other key features:
669669
GREEN = 1
670670
BLUE = 2
671671
672+
color = Color.GREEN
672673
match color:
673674
case Color.RED:
674675
print("I see red!")

Lib/asyncio/base_subprocess.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,9 @@ def _process_exited(self, returncode):
216216
self._proc.returncode = returncode
217217
self._call(self._protocol.process_exited)
218218
for p in self._pipes.values():
219-
p.pipe.close()
219+
if p is not None:
220+
p.pipe.close()
221+
220222
self._try_finish()
221223

222224
async def _wait(self):

Lib/enum.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1269,7 +1269,7 @@ class FlagBoundary(StrEnum):
12691269
STRICT, CONFORM, EJECT, KEEP = FlagBoundary
12701270

12711271

1272-
class Flag(Enum, boundary=STRICT):
1272+
class Flag(Enum, boundary=CONFORM):
12731273
"""
12741274
Support for flags
12751275
"""

Lib/test/test_enum.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2927,7 +2927,7 @@ def test_bool(self):
29272927
self.assertEqual(bool(f.value), bool(f))
29282928

29292929
def test_boundary(self):
2930-
self.assertIs(enum.Flag._boundary_, STRICT)
2930+
self.assertIs(enum.Flag._boundary_, CONFORM)
29312931
class Iron(Flag, boundary=STRICT):
29322932
ONE = 1
29332933
TWO = 2

Lib/test/test_long.py

+16
Original file line numberDiff line numberDiff line change
@@ -1518,6 +1518,22 @@ def __init__(self, value):
15181518
self.assertEqual(i, 1)
15191519
self.assertEqual(getattr(i, 'foo', 'none'), 'bar')
15201520

1521+
class ValidBytes:
1522+
def __bytes__(self):
1523+
return b'\x01'
1524+
class InvalidBytes:
1525+
def __bytes__(self):
1526+
return 'abc'
1527+
class MissingBytes: ...
1528+
class RaisingBytes:
1529+
def __bytes__(self):
1530+
1 / 0
1531+
1532+
self.assertEqual(int.from_bytes(ValidBytes()), 1)
1533+
self.assertRaises(TypeError, int.from_bytes, InvalidBytes())
1534+
self.assertRaises(TypeError, int.from_bytes, MissingBytes())
1535+
self.assertRaises(ZeroDivisionError, int.from_bytes, RaisingBytes())
1536+
15211537
@support.cpython_only
15221538
def test_from_bytes_small(self):
15231539
# bpo-46361

Lib/test/test_posix.py

+22
Original file line numberDiff line numberDiff line change
@@ -2090,6 +2090,28 @@ def test_mkdir(self):
20902090
with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
20912091
os.mkdir("dir", dir_fd=0)
20922092

2093+
def test_mkfifo(self):
2094+
self._verify_available("HAVE_MKFIFOAT")
2095+
if self.mac_ver >= (13, 0):
2096+
self.assertIn("HAVE_MKFIFOAT", posix._have_functions)
2097+
2098+
else:
2099+
self.assertNotIn("HAVE_MKFIFOAT", posix._have_functions)
2100+
2101+
with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2102+
os.mkfifo("path", dir_fd=0)
2103+
2104+
def test_mknod(self):
2105+
self._verify_available("HAVE_MKNODAT")
2106+
if self.mac_ver >= (13, 0):
2107+
self.assertIn("HAVE_MKNODAT", posix._have_functions)
2108+
2109+
else:
2110+
self.assertNotIn("HAVE_MKNODAT", posix._have_functions)
2111+
2112+
with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2113+
os.mknod("path", dir_fd=0)
2114+
20932115
def test_rename_replace(self):
20942116
self._verify_available("HAVE_RENAMEAT")
20952117
if self.mac_ver >= (10, 10):

Lib/test/test_unicode.py

+38
Original file line numberDiff line numberDiff line change
@@ -2945,6 +2945,44 @@ def test_asutf8andsize(self):
29452945
self.assertEqual(unicode_asutf8andsize(nonbmp), (b'\xf4\x8f\xbf\xbf', 4))
29462946
self.assertRaises(UnicodeEncodeError, unicode_asutf8andsize, 'a\ud800b\udfffc')
29472947

2948+
# Test PyUnicode_Count()
2949+
@support.cpython_only
2950+
@unittest.skipIf(_testcapi is None, 'need _testcapi module')
2951+
def test_count(self):
2952+
from _testcapi import unicode_count
2953+
2954+
st = 'abcabd'
2955+
self.assertEqual(unicode_count(st, 'a', 0, len(st)), 2)
2956+
self.assertEqual(unicode_count(st, 'ab', 0, len(st)), 2)
2957+
self.assertEqual(unicode_count(st, 'abc', 0, len(st)), 1)
2958+
self.assertEqual(unicode_count(st, 'а', 0, len(st)), 0) # cyrillic "a"
2959+
# start < end
2960+
self.assertEqual(unicode_count(st, 'a', 3, len(st)), 1)
2961+
self.assertEqual(unicode_count(st, 'a', 4, len(st)), 0)
2962+
self.assertEqual(unicode_count(st, 'a', 0, sys.maxsize), 2)
2963+
# start >= end
2964+
self.assertEqual(unicode_count(st, 'abc', 0, 0), 0)
2965+
self.assertEqual(unicode_count(st, 'a', 3, 2), 0)
2966+
self.assertEqual(unicode_count(st, 'a', sys.maxsize, 5), 0)
2967+
# negative
2968+
self.assertEqual(unicode_count(st, 'ab', -len(st), -1), 2)
2969+
self.assertEqual(unicode_count(st, 'a', -len(st), -3), 1)
2970+
# wrong args
2971+
self.assertRaises(TypeError, unicode_count, 'a', 'a')
2972+
self.assertRaises(TypeError, unicode_count, 'a', 'a', 1)
2973+
self.assertRaises(TypeError, unicode_count, 1, 'a', 0, 1)
2974+
self.assertRaises(TypeError, unicode_count, 'a', 1, 0, 1)
2975+
# empty string
2976+
self.assertEqual(unicode_count('abc', '', 0, 3), 4)
2977+
self.assertEqual(unicode_count('abc', '', 1, 3), 3)
2978+
self.assertEqual(unicode_count('', '', 0, 1), 1)
2979+
self.assertEqual(unicode_count('', 'a', 0, 1), 0)
2980+
# different unicode kinds
2981+
for uni in "\xa1", "\u8000\u8080", "\ud800\udc02", "\U0001f100\U0001f1f1":
2982+
for ch in uni:
2983+
self.assertEqual(unicode_count(uni, ch, 0, len(uni)), 1)
2984+
self.assertEqual(unicode_count(st, ch, 0, len(st)), 0)
2985+
29482986
# Test PyUnicode_FindChar()
29492987
@support.cpython_only
29502988
@unittest.skipIf(_testcapi is None, 'need _testcapi module')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
fix Flag to use boundary CONFORM
2+
3+
This restores previous Flag behavior of allowing flags with non-sequential values to be combined; e.g.
4+
5+
class Skip(Flag):
6+
TWO = 2
7+
EIGHT = 8
8+
9+
Skip.TWO | Skip.EIGHT -> <Skip.TWO|EIGHT: 10>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
The macOS 13 SDK includes support for the ``mkfifoat`` and ``mknodat`` system calls.
2+
Using the ``dir_fd`` option with either :func:`os.mkfifo` or :func:`os.mknod` could result in a
3+
segfault if cpython is built with the macOS 13 SDK but run on an earlier
4+
version of macOS. Prevent this by adding runtime support for detection of
5+
these system calls ("weaklinking") as is done for other newer syscalls on
6+
macOS.

0 commit comments

Comments
 (0)