Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions Doc/faq/general.rst
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,11 @@ Alpha, beta and release candidate versions have an additional suffix:
In other words, all versions labeled *2.0aN* precede the versions labeled
*2.0bN*, which precede versions labeled *2.0rcN*, and *those* precede 2.0.

You may also find version numbers with a "+" suffix, e.g. "2.2+". These are
unreleased versions, built directly from the CPython development repository. In
practice, after a final minor release is made, the version is incremented to the
next minor version, which becomes the "a0" version, e.g. "2.4a0".
You may also find version numbers with a "+dev" suffix, such as "3.15.0b3+dev".
These are unreleased versions, built directly from the CPython development
repository. After the first beta release is made, the version is
incremented to the next feature version, which becomes the "a0" version,
such as "3.16.0a0".

See the `Developer's Guide
<https://devguide.python.org/developer-workflow/development-cycle/>`__
Expand Down
8 changes: 8 additions & 0 deletions Lib/test/libregrtest/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ def setup_process() -> None:
for signum in signals:
faulthandler.register(signum, chain=True, file=stderr_fd)

# Restore the default SIGINT handler if there is no Python-level
# handler. Python inherits the SIG_IGN disposition when the test
# suite runs as a shell background job; then asyncio.Runner does not
# install its own handler and _thread.interrupt_main() is a no-op,
# which makes some tests in test_asyncio and test_threading hang.
if signal.getsignal(signal.SIGINT) in (signal.SIG_IGN, signal.SIG_DFL):
signal.signal(signal.SIGINT, signal.default_int_handler)

adjust_rlimit_nofile()

support.record_original_stdout(sys.stdout)
Expand Down
11 changes: 6 additions & 5 deletions Lib/test/test_mmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -907,9 +907,10 @@ def test_resize_up_anonymous_mapping(self):

with mmap.mmap(-1, start_size) as m:
m[:] = data
if sys.platform.startswith(('linux', 'android')):
# Can't expand a shared anonymous mapping on Linux.
# See https://bugzilla.kernel.org/show_bug.cgi?id=8691
if sys.platform.startswith(('linux', 'android', 'netbsd')):
# Can't expand a shared anonymous mapping on Linux
# (see https://bugzilla.kernel.org/show_bug.cgi?id=8691)
# or NetBSD.
with self.assertRaises(ValueError):
m.resize(new_size)
else:
Expand Down Expand Up @@ -1175,8 +1176,8 @@ def test_flush_parameters(self):
if hasattr(mmap, 'MS_INVALIDATE'):
m.flush(PAGESIZE * 2, flags=mmap.MS_INVALIDATE)
if hasattr(mmap, 'MS_ASYNC') and hasattr(mmap, 'MS_INVALIDATE'):
if sys.platform == 'freebsd':
# FreeBSD doesn't support this combination
if sys.platform.startswith(('freebsd', 'dragonfly')):
# FreeBSD and DragonFly don't support this combination
with self.assertRaises(OSError) as cm:
m.flush(0, PAGESIZE, flags=mmap.MS_ASYNC | mmap.MS_INVALIDATE)
self.assertEqual(cm.exception.errno, errno.EINVAL)
Expand Down
18 changes: 18 additions & 0 deletions Lib/test/test_socket.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@
# SCM_RIGHTS control message when several are sent in a single sendmsg().
BSD_COMBINES_SCM_RIGHTS = sys.platform.startswith(
("netbsd", "openbsd", "dragonfly"))
# OpenBSD and DragonFly fail recvmsg() with EMSGSIZE, instead of setting
# MSG_CTRUNC, when the ancillary data buffer is too small for a cmsghdr.
CMSG_TRUNC_RAISES_EMSGSIZE = sys.platform.startswith(("openbsd", "dragonfly"))
WSL = "microsoft-standard-WSL" in platform.release()

try:
Expand Down Expand Up @@ -4351,6 +4354,7 @@ def _testCmsgTrunc0(self):
# (but still too small) buffer sizes.

@skipForRefleakHuntinIf(sys.platform == "darwin", "#80931")
@unittest.skipIf(CMSG_TRUNC_RAISES_EMSGSIZE, "skipping, see gh-154240")
def testCmsgTrunc1(self):
self.checkTruncatedHeader(self.doRecvmsg(self.serv_sock, len(MSG), 1))

Expand All @@ -4359,6 +4363,7 @@ def _testCmsgTrunc1(self):
self.createAndSendFDs(1)

@skipForRefleakHuntinIf(sys.platform == "darwin", "#80931")
@unittest.skipIf(CMSG_TRUNC_RAISES_EMSGSIZE, "skipping, see gh-154240")
def testCmsgTrunc2Int(self):
# The cmsghdr structure has at least three members, two of
# which are ints, so we still shouldn't see any ancillary
Expand All @@ -4371,6 +4376,7 @@ def _testCmsgTrunc2Int(self):
self.createAndSendFDs(1)

@skipForRefleakHuntinIf(sys.platform == "darwin", "#80931")
@unittest.skipIf(CMSG_TRUNC_RAISES_EMSGSIZE, "skipping, see gh-154240")
def testCmsgTruncLen0Minus1(self):
self.checkTruncatedHeader(self.doRecvmsg(self.serv_sock, len(MSG),
socket.CMSG_LEN(0) - 1))
Expand Down Expand Up @@ -4408,6 +4414,7 @@ def checkTruncatedArray(self, ancbuf, maxdata, mindata=0):
self.checkFDs(fds)

@skipForRefleakHuntinIf(sys.platform == "darwin", "#80931")
@unittest.skipIf(CMSG_TRUNC_RAISES_EMSGSIZE, "skipping, see gh-154240")
def testCmsgTruncLen0(self):
self.checkTruncatedArray(ancbuf=socket.CMSG_LEN(0), maxdata=0)

Expand All @@ -4416,6 +4423,7 @@ def _testCmsgTruncLen0(self):
self.createAndSendFDs(1)

@skipForRefleakHuntinIf(sys.platform == "darwin", "#80931")
@unittest.skipIf(CMSG_TRUNC_RAISES_EMSGSIZE, "skipping, see gh-154240")
def testCmsgTruncLen0Plus1(self):
self.checkTruncatedArray(ancbuf=socket.CMSG_LEN(0) + 1, maxdata=1)

Expand All @@ -4424,6 +4432,7 @@ def _testCmsgTruncLen0Plus1(self):
self.createAndSendFDs(2)

@skipForRefleakHuntinIf(sys.platform == "darwin", "#80931")
@unittest.skipIf(CMSG_TRUNC_RAISES_EMSGSIZE, "skipping, see gh-154240")
def testCmsgTruncLen1(self):
self.checkTruncatedArray(ancbuf=socket.CMSG_LEN(SIZEOF_INT),
maxdata=SIZEOF_INT)
Expand All @@ -4434,6 +4443,7 @@ def _testCmsgTruncLen1(self):


@skipForRefleakHuntinIf(sys.platform == "darwin", "#80931")
@unittest.skipIf(CMSG_TRUNC_RAISES_EMSGSIZE, "skipping, see gh-154240")
def testCmsgTruncLen2Minus1(self):
self.checkTruncatedArray(ancbuf=socket.CMSG_LEN(2 * SIZEOF_INT) - 1,
maxdata=(2 * SIZEOF_INT) - 1)
Expand Down Expand Up @@ -4706,6 +4716,7 @@ def _testSingleCmsgTrunc0(self):
# (but still too small) buffer sizes.

@requireAttrs(socket, "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT")
@unittest.skipIf(CMSG_TRUNC_RAISES_EMSGSIZE, "skipping, see gh-154240")
def testSingleCmsgTrunc1(self):
self.checkHopLimitTruncatedHeader(ancbufsize=1)

Expand All @@ -4715,6 +4726,7 @@ def _testSingleCmsgTrunc1(self):
self.sendToServer(MSG)

@requireAttrs(socket, "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT")
@unittest.skipIf(CMSG_TRUNC_RAISES_EMSGSIZE, "skipping, see gh-154240")
def testSingleCmsgTrunc2Int(self):
self.checkHopLimitTruncatedHeader(ancbufsize=2 * SIZEOF_INT)

Expand All @@ -4724,6 +4736,7 @@ def _testSingleCmsgTrunc2Int(self):
self.sendToServer(MSG)

@requireAttrs(socket, "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT")
@unittest.skipIf(CMSG_TRUNC_RAISES_EMSGSIZE, "skipping, see gh-154240")
def testSingleCmsgTruncLen0Minus1(self):
self.checkHopLimitTruncatedHeader(ancbufsize=socket.CMSG_LEN(0) - 1)

Expand All @@ -4733,6 +4746,7 @@ def _testSingleCmsgTruncLen0Minus1(self):
self.sendToServer(MSG)

@requireAttrs(socket, "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT")
@unittest.skipIf(CMSG_TRUNC_RAISES_EMSGSIZE, "skipping, see gh-154240")
def testSingleCmsgTruncInData(self):
# Test truncation of a control message inside its associated
# data. The message may be returned with its data truncated,
Expand Down Expand Up @@ -4805,6 +4819,7 @@ def _testSecondCmsgTrunc0(self):

@requireAttrs(socket, "CMSG_SPACE", "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT",
"IPV6_RECVTCLASS", "IPV6_TCLASS")
@unittest.skipIf(CMSG_TRUNC_RAISES_EMSGSIZE, "skipping, see gh-154240")
def testSecondCmsgTrunc1(self):
self.checkTruncatedSecondHeader(socket.CMSG_SPACE(SIZEOF_INT) + 1)

Expand All @@ -4815,6 +4830,7 @@ def _testSecondCmsgTrunc1(self):

@requireAttrs(socket, "CMSG_SPACE", "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT",
"IPV6_RECVTCLASS", "IPV6_TCLASS")
@unittest.skipIf(CMSG_TRUNC_RAISES_EMSGSIZE, "skipping, see gh-154240")
def testSecondCmsgTrunc2Int(self):
self.checkTruncatedSecondHeader(socket.CMSG_SPACE(SIZEOF_INT) +
2 * SIZEOF_INT)
Expand All @@ -4826,6 +4842,7 @@ def _testSecondCmsgTrunc2Int(self):

@requireAttrs(socket, "CMSG_SPACE", "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT",
"IPV6_RECVTCLASS", "IPV6_TCLASS")
@unittest.skipIf(CMSG_TRUNC_RAISES_EMSGSIZE, "skipping, see gh-154240")
def testSecondCmsgTruncLen0Minus1(self):
self.checkTruncatedSecondHeader(socket.CMSG_SPACE(SIZEOF_INT) +
socket.CMSG_LEN(0) - 1)
Expand All @@ -4837,6 +4854,7 @@ def _testSecondCmsgTruncLen0Minus1(self):

@requireAttrs(socket, "CMSG_SPACE", "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT",
"IPV6_RECVTCLASS", "IPV6_TCLASS")
@unittest.skipIf(CMSG_TRUNC_RAISES_EMSGSIZE, "skipping, see gh-154240")
def testSecondCmsgTruncInData(self):
# Test truncation of the second of two control messages inside
# its associated data.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fix a crash in :meth:`mmap.mmap.resize` on NetBSD when growing a shared
anonymous mapping. :meth:`!resize` now raises :exc:`ValueError` in this
case, as it already did on Linux.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
The test runner (regrtest) now restores the default SIGINT handler if it
was inherited as ignored, so the test suite no longer hangs when run as
a shell background job.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
``_winapi``: implement ``GetVersion()`` UWP alternative.
12 changes: 12 additions & 0 deletions Modules/_winapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1739,7 +1739,19 @@ _winapi_GetVersion_impl(PyObject *module)
#pragma warning(disable:4996)

{
#ifdef MS_WINDOWS_DESKTOP
return GetVersion();
#else
OSVERSIONINFOW version_info;
ZeroMemory(&version_info, sizeof(version_info));
version_info.dwOSVersionInfoSize = sizeof(version_info);
if (GetVersionExW(&version_info)) {
return version_info.dwMinorVersion |
(version_info.dwMajorVersion << 8) |
(version_info.dwBuildNumber << 16);
}
return 0;
#endif
}

#pragma warning(pop)
Expand Down
7 changes: 5 additions & 2 deletions Modules/mmapmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -969,10 +969,13 @@ mmap_mmap_resize_impl(mmap_object *self, Py_ssize_t new_size)
#ifdef UNIX
void *newmap;

#ifdef __linux__
#if defined(__linux__) || defined(__NetBSD__)
// Linux mremap() refuses to grow a shared anonymous mapping, and
// NetBSD mremap() returns a mapping whose grown region is not backed,
// so accessing it crashes. Reject it here in both cases.
if (self->fd == -1 && !(self->flags & MAP_PRIVATE) && new_size > self->size) {
PyErr_Format(PyExc_ValueError,
"mmap: can't expand a shared anonymous mapping on Linux");
"mmap: can't expand a shared anonymous mapping");
return NULL;
}
#endif
Expand Down
Loading