diff --git a/gnu/local.mk b/gnu/local.mk index 5603c4a9ec..a68e946151 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -1554,8 +1554,6 @@ dist_patch_DATA = \ %D%/packages/patches/python-3-search-paths.patch \ %D%/packages/patches/python-3-fix-tests.patch \ %D%/packages/patches/python-3-hurd-configure.patch \ - %D%/packages/patches/python-3.8-CVE-2021-3177.patch \ - %D%/packages/patches/python-3.9-fix-tests.patch \ %D%/packages/patches/python-CVE-2018-14647.patch \ %D%/packages/patches/python-CVE-2020-26116.patch \ %D%/packages/patches/python-aionotify-0.2.0-py3.8.patch \ diff --git a/gnu/packages/patches/python-3.8-CVE-2021-3177.patch b/gnu/packages/patches/python-3.8-CVE-2021-3177.patch deleted file mode 100644 index 01f6b52865..0000000000 --- a/gnu/packages/patches/python-3.8-CVE-2021-3177.patch +++ /dev/null @@ -1,194 +0,0 @@ -Fix CVE-2021-3177 for Python 3.8: - -https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-3177 - -Patch copied from upstream source repository: - -https://github.com/python/cpython/commit/ece5dfd403dac211f8d3c72701fe7ba7b7aa5b5f - -From ece5dfd403dac211f8d3c72701fe7ba7b7aa5b5f Mon Sep 17 00:00:00 2001 -From: "Miss Islington (bot)" - <31488909+miss-islington@users.noreply.github.com> -Date: Mon, 18 Jan 2021 13:28:52 -0800 -Subject: [PATCH] closes bpo-42938: Replace snprintf with Python unicode - formatting in ctypes param reprs. (GH-24248) - -(cherry picked from commit 916610ef90a0d0761f08747f7b0905541f0977c7) - -Co-authored-by: Benjamin Peterson - -Co-authored-by: Benjamin Peterson ---- - Lib/ctypes/test/test_parameters.py | 43 ++++++++++++++++ - .../2021-01-18-09-27-31.bpo-42938.4Zn4Mp.rst | 2 + - Modules/_ctypes/callproc.c | 51 +++++++------------ - 3 files changed, 64 insertions(+), 32 deletions(-) - create mode 100644 Misc/NEWS.d/next/Security/2021-01-18-09-27-31.bpo-42938.4Zn4Mp.rst - -diff --git a/Lib/ctypes/test/test_parameters.py b/Lib/ctypes/test/test_parameters.py -index e4c25fd880cef..531894fdec838 100644 ---- a/Lib/ctypes/test/test_parameters.py -+++ b/Lib/ctypes/test/test_parameters.py -@@ -201,6 +201,49 @@ def __dict__(self): - with self.assertRaises(ZeroDivisionError): - WorseStruct().__setstate__({}, b'foo') - -+ def test_parameter_repr(self): -+ from ctypes import ( -+ c_bool, -+ c_char, -+ c_wchar, -+ c_byte, -+ c_ubyte, -+ c_short, -+ c_ushort, -+ c_int, -+ c_uint, -+ c_long, -+ c_ulong, -+ c_longlong, -+ c_ulonglong, -+ c_float, -+ c_double, -+ c_longdouble, -+ c_char_p, -+ c_wchar_p, -+ c_void_p, -+ ) -+ self.assertRegex(repr(c_bool.from_param(True)), r"^$") -+ self.assertEqual(repr(c_char.from_param(97)), "") -+ self.assertRegex(repr(c_wchar.from_param('a')), r"^$") -+ self.assertEqual(repr(c_byte.from_param(98)), "") -+ self.assertEqual(repr(c_ubyte.from_param(98)), "") -+ self.assertEqual(repr(c_short.from_param(511)), "") -+ self.assertEqual(repr(c_ushort.from_param(511)), "") -+ self.assertRegex(repr(c_int.from_param(20000)), r"^$") -+ self.assertRegex(repr(c_uint.from_param(20000)), r"^$") -+ self.assertRegex(repr(c_long.from_param(20000)), r"^$") -+ self.assertRegex(repr(c_ulong.from_param(20000)), r"^$") -+ self.assertRegex(repr(c_longlong.from_param(20000)), r"^$") -+ self.assertRegex(repr(c_ulonglong.from_param(20000)), r"^$") -+ self.assertEqual(repr(c_float.from_param(1.5)), "") -+ self.assertEqual(repr(c_double.from_param(1.5)), "") -+ self.assertEqual(repr(c_double.from_param(1e300)), "") -+ self.assertRegex(repr(c_longdouble.from_param(1.5)), r"^$") -+ self.assertRegex(repr(c_char_p.from_param(b'hihi')), "^$") -+ self.assertRegex(repr(c_wchar_p.from_param('hihi')), "^$") -+ self.assertRegex(repr(c_void_p.from_param(0x12)), r"^$") -+ - ################################################################ - - if __name__ == '__main__': -#diff --git a/Misc/NEWS.d/next/Security/2021-01-18-09-27-31.bpo-42938.4Zn4Mp.rst b/Misc/NEWS.d/next/Security/2021-01-18-09-27-31.bpo-42938.4Zn4Mp.rst -#new file mode 100644 -#index 0000000000000..7df65a156feab -#--- /dev/null -#+++ b/Misc/NEWS.d/next/Security/2021-01-18-09-27-31.bpo-42938.4Zn4Mp.rst -#@@ -0,0 +1,2 @@ -#+Avoid static buffers when computing the repr of :class:`ctypes.c_double` and -#+:class:`ctypes.c_longdouble` values. -diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c -index a9b8675cd951b..de75918d49f37 100644 ---- a/Modules/_ctypes/callproc.c -+++ b/Modules/_ctypes/callproc.c -@@ -484,58 +484,47 @@ is_literal_char(unsigned char c) - static PyObject * - PyCArg_repr(PyCArgObject *self) - { -- char buffer[256]; - switch(self->tag) { - case 'b': - case 'B': -- sprintf(buffer, "", -+ return PyUnicode_FromFormat("", - self->tag, self->value.b); -- break; - case 'h': - case 'H': -- sprintf(buffer, "", -+ return PyUnicode_FromFormat("", - self->tag, self->value.h); -- break; - case 'i': - case 'I': -- sprintf(buffer, "", -+ return PyUnicode_FromFormat("", - self->tag, self->value.i); -- break; - case 'l': - case 'L': -- sprintf(buffer, "", -+ return PyUnicode_FromFormat("", - self->tag, self->value.l); -- break; - - case 'q': - case 'Q': -- sprintf(buffer, --#ifdef MS_WIN32 -- "", --#else -- "", --#endif -+ return PyUnicode_FromFormat("", - self->tag, self->value.q); -- break; - case 'd': -- sprintf(buffer, "", -- self->tag, self->value.d); -- break; -- case 'f': -- sprintf(buffer, "", -- self->tag, self->value.f); -- break; -- -+ case 'f': { -+ PyObject *f = PyFloat_FromDouble((self->tag == 'f') ? self->value.f : self->value.d); -+ if (f == NULL) { -+ return NULL; -+ } -+ PyObject *result = PyUnicode_FromFormat("", self->tag, f); -+ Py_DECREF(f); -+ return result; -+ } - case 'c': - if (is_literal_char((unsigned char)self->value.c)) { -- sprintf(buffer, "", -+ return PyUnicode_FromFormat("", - self->tag, self->value.c); - } - else { -- sprintf(buffer, "", -+ return PyUnicode_FromFormat("", - self->tag, (unsigned char)self->value.c); - } -- break; - - /* Hm, are these 'z' and 'Z' codes useful at all? - Shouldn't they be replaced by the functionality of c_string -@@ -544,22 +533,20 @@ PyCArg_repr(PyCArgObject *self) - case 'z': - case 'Z': - case 'P': -- sprintf(buffer, "", -+ return PyUnicode_FromFormat("", - self->tag, self->value.p); - break; - - default: - if (is_literal_char((unsigned char)self->tag)) { -- sprintf(buffer, "", -+ return PyUnicode_FromFormat("", - (unsigned char)self->tag, (void *)self); - } - else { -- sprintf(buffer, "", -+ return PyUnicode_FromFormat("", - (unsigned char)self->tag, (void *)self); - } -- break; - } -- return PyUnicode_FromString(buffer); - } - - static PyMemberDef PyCArgType_members[] = { diff --git a/gnu/packages/patches/python-3.9-fix-tests.patch b/gnu/packages/patches/python-3.9-fix-tests.patch deleted file mode 100644 index dc6b8c4cc8..0000000000 --- a/gnu/packages/patches/python-3.9-fix-tests.patch +++ /dev/null @@ -1,370 +0,0 @@ -See the discussion about the issues fixed here at: -http://bugs.python.org/issue20868 . - -diff --git a/Lib/ctypes/test/test_callbacks.py b/Lib/ctypes/test/test_callbacks.py ---- a/Lib/ctypes/test/test_callbacks.py -+++ b/Lib/ctypes/test/test_callbacks.py -@@ -3,6 +3,7 @@ import unittest - from ctypes import * - from ctypes.test import need_symbol - import _ctypes_test -+import platform - - class Callbacks(unittest.TestCase): - functype = CFUNCTYPE -@@ -176,6 +177,8 @@ class SampleCallbacksTestCase(unittest.TestCase): - - self.assertLess(diff, 0.01, "%s not less than 0.01" % diff) - -+ @unittest.skipIf(platform.machine() in ['mips64'], -+ "This test fails on this platform") - def test_issue_8959_a(self): - from ctypes.util import find_library - libc_path = find_library("c") -diff --git a/Lib/ctypes/test/test_libc.py b/Lib/ctypes/test/test_libc.py ---- a/Lib/ctypes/test/test_libc.py -+++ b/Lib/ctypes/test/test_libc.py -@@ -2,6 +2,7 @@ import unittest - - from ctypes import * - import _ctypes_test -+import platform - - lib = CDLL(_ctypes_test.__file__) - -@@ -17,6 +18,8 @@ class LibTest(unittest.TestCase): - import math - self.assertEqual(lib.my_sqrt(2.0), math.sqrt(2.0)) - -+ @unittest.skipIf(platform.machine() in ['mips64'], -+ "This test fails on this platform") - def test_qsort(self): - comparefunc = CFUNCTYPE(c_int, POINTER(c_char), POINTER(c_char)) - lib.my_qsort.argtypes = c_void_p, c_size_t, c_size_t, comparefunc -diff --git a/Lib/distutils/tests/test_archive_util.py b/Lib/distutils/tests/test_archive_util.py ---- a/Lib/distutils/tests/test_archive_util.py -+++ b/Lib/distutils/tests/test_archive_util.py -@@ -333,6 +333,7 @@ class ArchiveUtilTestCase(support.TempdirManager, - self.assertEqual(os.path.basename(res), 'archive.tar.xz') - self.assertEqual(self._tarinfo(res), self._created_files) - -+ @unittest.skipIf(True, "getgrgid(0)[0] raises a KeyError on Guix") - def test_make_archive_owner_group(self): - # testing make_archive with owner and group, with various combinations - # this works even if there's not gid/uid support -@@ -362,6 +363,7 @@ class ArchiveUtilTestCase(support.TempdirManager, - - @unittest.skipUnless(ZLIB_SUPPORT, "Requires zlib") - @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support") -+ @unittest.skipIf(True, "getgrgid(0)[0] raises a KeyError on Guix") - def test_tarfile_root_owner(self): - tmpdir = self._create_files() - base_name = os.path.join(self.mkdtemp(), 'archive') -diff --git a/Lib/distutils/tests/test_sdist.py b/Lib/distutils/tests/test_sdist.py ---- a/Lib/distutils/tests/test_sdist.py -+++ b/Lib/distutils/tests/test_sdist.py -@@ -443,6 +443,7 @@ class SDistTestCase(BasePyPIRCCommandTestCase): - "The tar command is not found") - @unittest.skipIf(find_executable('gzip') is None, - "The gzip command is not found") -+ @unittest.skipIf(True, "getgrgid(0)[0] raises a KeyError on Guix") - def test_make_distribution_owner_group(self): - # now building a sdist - dist, cmd = self.get_cmd() -diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py ---- a/Lib/test/_test_multiprocessing.py -+++ b/Lib/test/_test_multiprocessing.py -@@ -1473,6 +1473,7 @@ class _TestCondition(BaseTestCase): - if pid is not None: - os.kill(pid, signal.SIGINT) - -+ @unittest.skipIf(True, "This fails for unknown reasons on Guix") - def test_wait_result(self): - if isinstance(self, ProcessesMixin) and sys.platform != 'win32': - pid = os.getpid() -diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py ---- a/Lib/test/test_asyncio/test_base_events.py -+++ b/Lib/test/test_asyncio/test_base_events.py -@@ -1323,6 +1323,8 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): - self._test_create_connection_ip_addr(m_socket, False) - - @patch_socket -+ @unittest.skipUnless(support.is_resource_enabled('network'), -+ 'network is not enabled') - def test_create_connection_service_name(self, m_socket): - m_socket.getaddrinfo = socket.getaddrinfo - sock = m_socket.socket.return_value -diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py ---- a/Lib/test/test_generators.py -+++ b/Lib/test/test_generators.py -@@ -34,6 +34,7 @@ class SignalAndYieldFromTest(unittest.TestCase): - else: - return "FAILED" - -+ @unittest.skipIf(True, 'Keyboard interrupts do not work in the Guix build environment') - def test_raise_and_yield_from(self): - gen = self.generator1() - gen.send(None) -diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py ---- a/Lib/test/test_pathlib.py -+++ b/Lib/test/test_pathlib.py -@@ -2134,8 +2134,7 @@ class PosixPathTest(_BasePathTest, unittest.TestCase): - self.assertEqual(given, expect) - self.assertEqual(set(p.rglob("FILEd*")), set()) - -- @unittest.skipUnless(hasattr(pwd, 'getpwall'), -- 'pwd module does not expose getpwall()') -+ @unittest.skipIf(True, "Guix builder home is '/' which causes trouble for these tests") - def test_expanduser(self): - P = self.cls - support.import_module('pwd') -diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py ---- a/Lib/test/test_pdb.py -+++ b/Lib/test/test_pdb.py -@@ -1150,11 +1150,11 @@ def test_pdb_issue_20766(): - > (6)test_function() - -> print('pdb %d: %s' % (i, sess._previous_sigint_handler)) - (Pdb) continue -- pdb 1: -+ pdb 1: Handlers.SIG_IGN - > (5)test_function() - -> sess.set_trace(sys._getframe()) - (Pdb) continue -- pdb 2: -+ pdb 2: Handlers.SIG_IGN - """ - - -diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py ---- a/Lib/test/test_regrtest.py -+++ b/Lib/test/test_regrtest.py -@@ -762,6 +762,7 @@ class ArgsTestCase(BaseTestCase): - output = self.run_tests('--fromfile', filename) - self.check_executed_tests(output, tests) - -+ @unittest.skipIf(True, 'Keyboard interrupts do not work in the Guix build environment.') - def test_interrupted(self): - code = TEST_INTERRUPTED - test = self.create_test('sigint', code=code) -@@ -779,6 +780,7 @@ class ArgsTestCase(BaseTestCase): - % (self.TESTNAME_REGEX, len(tests))) - self.check_line(output, regex) - -+ @unittest.skipIf(True, 'Keyboard interrupts do not work in the Guix build environment.') - def test_slowest_interrupted(self): - # Issue #25373: test --slowest with an interrupted test - code = TEST_INTERRUPTED -diff --git a/Lib/test/test_resource.py b/Lib/test/test_resource.py ---- a/Lib/test/test_resource.py -+++ b/Lib/test/test_resource.py -@@ -145,6 +145,7 @@ class ResourceTest(unittest.TestCase): - - @unittest.skipUnless(hasattr(resource, 'prlimit'), 'no prlimit') - @support.requires_linux_version(2, 6, 36) -+ @unittest.skipIf(True, "Bug: the PermissionError is not raised") - def test_prlimit(self): - self.assertRaises(TypeError, resource.prlimit) - self.assertRaises(ProcessLookupError, resource.prlimit, -diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py ---- a/Lib/test/test_shutil.py -+++ b/Lib/test/test_shutil.py -@@ -1428,6 +1428,7 @@ class TestArchives(BaseTest, unittest.TestCase): - self.assertRaises(ValueError, make_archive, base_name, 'xxx') - - @support.requires_zlib() -+ @unittest.skipIf(True, "getgrgid(0)[0] raises a KeyError on Guix") - def test_make_archive_owner_group(self): - # testing make_archive with owner and group, with various combinations - # this works even if there's not gid/uid support -@@ -1456,6 +1457,7 @@ class TestArchives(BaseTest, unittest.TestCase): - - - @support.requires_zlib() -+ @unittest.skipIf(True, "getgrgid(0)[0] raises a KeyError on Guix") - @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support") - def test_tarfile_root_owner(self): - root_dir, base_dir = self._create_files() -diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py ---- a/Lib/test/test_unicodedata.py -+++ b/Lib/test/test_unicodedata.py -@@ -320,6 +320,7 @@ class NormalizationTest(unittest.TestCase): - data = [int(x, 16) for x in data.split(" ")] - return "".join([chr(x) for x in data]) - -+ @unittest.skipIf(True, 'Network is not available in the Guix build environment') - def test_normalization(self): - TESTDATAFILE = "NormalizationTest.txt" - TESTDATAURL = f"http://www.pythontest.net/unicode/{unicodedata.unidata_version}/{TESTDATAFILE}" -diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py ---- a/Lib/test/test_socket.py -+++ b/Lib/test/test_socket.py -@@ -875,6 +875,8 @@ class GeneralModuleTests(unittest.TestCase): - if not fqhn in all_host_names: - self.fail("Error testing host resolution mechanisms. (fqdn: %s, all: %s)" % (fqhn, repr(all_host_names))) - -+ @unittest.skipUnless(support.is_resource_enabled('network'), -+ 'network is not enabled') - def test_host_resolution(self): - for addr in [support.HOSTv4, '10.0.0.1', '255.255.255.255']: - self.assertEqual(socket.gethostbyname(addr), addr) -@@ -1004,6 +1006,8 @@ class GeneralModuleTests(unittest.TestCase): - self.assertWarns(DeprecationWarning, socket.ntohs, k) - self.assertWarns(DeprecationWarning, socket.htons, k) - -+ @unittest.skipUnless(os.path.exists("/etc/services"), -+ "getservbyname uses /etc/services, which is not in the chroot") - def testGetServBy(self): - eq = self.assertEqual - # Find one service that exists, then check all the related interfaces. -@@ -1358,6 +1362,8 @@ class GeneralModuleTests(unittest.TestCase): - raise - self.assertRaises(TypeError, s.ioctl, socket.SIO_LOOPBACK_FAST_PATH, None) - -+ @unittest.skipUnless(os.path.exists("/etc/gai.conf"), -+ "getaddrinfo() will fail") - def testGetaddrinfo(self): - try: - socket.getaddrinfo('localhost', 80) -@@ -1440,6 +1446,8 @@ class GeneralModuleTests(unittest.TestCase): - # only IP addresses are allowed - self.assertRaises(OSError, socket.getnameinfo, ('mail.python.org',0), 0) - -+ @unittest.skipUnless(os.path.exists("/etc/gai.conf"), -+ "getaddrinfo() will fail") - @unittest.skipUnless(support.is_resource_enabled('network'), - 'network is not enabled') - def test_idna(self): -diff --git a/Lib/test/test_spwd.py b/Lib/test/test_spwd.py ---- a/Lib/test/test_spwd.py -+++ b/Lib/test/test_spwd.py -@@ -5,8 +5,7 @@ from test import support - spwd = support.import_module('spwd') - - --@unittest.skipUnless(hasattr(os, 'geteuid') and os.geteuid() == 0, -- 'root privileges required') -+@unittest.skipUnless(os.path.exists("/etc/shadow"), 'spwd tests require /etc/shadow') - class TestSpwdRoot(unittest.TestCase): - - def test_getspall(self): -@@ -56,8 +55,7 @@ class TestSpwdRoot(unittest.TestCase): - self.assertRaises(TypeError, spwd.getspnam, bytes_name) - - --@unittest.skipUnless(hasattr(os, 'geteuid') and os.geteuid() != 0, -- 'non-root user required') -+@unittest.skipUnless(os.path.exists("/etc/shadow"), 'spwd tests require /etc/shadow') - class TestSpwdNonRoot(unittest.TestCase): - - def test_getspnam_exception(self): -diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py ---- a/Lib/test/test_tarfile.py -+++ b/Lib/test/test_tarfile.py -@@ -2509,9 +2509,12 @@ def root_is_uid_gid_0(): - import pwd, grp - except ImportError: - return False -- if pwd.getpwuid(0)[0] != 'root': -- return False -- if grp.getgrgid(0)[0] != 'root': -+ try: -+ if pwd.getpwuid(0)[0] != 'root': -+ return False -+ if grp.getgrgid(0)[0] != 'root': -+ return False -+ except KeyError: - return False - return True - -diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py ---- a/Lib/test/test_threading.py -+++ b/Lib/test/test_threading.py -@@ -1249,6 +1249,7 @@ class MiscTestCase(unittest.TestCase): - - - class InterruptMainTests(unittest.TestCase): -+ @unittest.skipIf(True, 'Keyboard interrupts do not work in the Guix build container.') - def test_interrupt_main_subthread(self): - # Calling start_new_thread with a function that executes interrupt_main - # should raise KeyboardInterrupt upon completion. -@@ -1260,6 +1261,8 @@ class InterruptMainTests(unittest.TestCase): - t.join() - t.join() - -+ -+ @unittest.skipIf(True, 'Keyboard interrupts do not work in the Guix build container.') - def test_interrupt_main_mainthread(self): - # Make sure that if interrupt_main is called in main thread that - # KeyboardInterrupt is raised instantly. -diff --git a/Tools/scripts/run_tests.py b/Tools/scripts/run_tests.py ---- a/Tools/scripts/run_tests.py -+++ b/Tools/scripts/run_tests.py -@@ -39,7 +39,7 @@ def main(regrtest_args): - if not any(is_multiprocess_flag(arg) for arg in regrtest_args): - args.extend(['-j', '0']) # Use all CPU cores - if not any(is_resource_use_flag(arg) for arg in regrtest_args): -- args.extend(['-u', 'all,-largefile,-audio,-gui']) -+ args.extend(['-u', 'all,-largefile,-audio,-gui,-network']) - args.extend(regrtest_args) - print(' '.join(args)) - if sys.platform == 'win32': -diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py -index 1474624..887f8ee 100644 ---- a/Lib/test/_test_multiprocessing.py -+++ b/Lib/test/_test_multiprocessing.py -@@ -3801,6 +3801,7 @@ class _TestSharedMemory(BaseTestCase): - sms.close() - - @unittest.skipIf(os.name != "posix", "not feasible in non-posix platforms") -+ @unittest.skipUnless(sys.stdin.isatty(), "KeyboardInterrupts require a TTY device") - def test_shared_memory_SharedMemoryServer_ignores_sigint(self): - # bpo-36368: protect SharedMemoryManager server process from - # KeyboardInterrupt signals. -diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py -index d41e94b..a1c15e7 100644 ---- a/Lib/test/test_signal.py -+++ b/Lib/test/test_signal.py -@@ -78,6 +78,7 @@ class PosixTests(unittest.TestCase): - self.assertLess(len(s), signal.NSIG) - - @unittest.skipUnless(sys.executable, "sys.executable required.") -+ @unittest.skipUnless(sys.stdin.isatty(), "KeyboardInterrupts require a TTY device") - def test_keyboard_interrupt_exit_code(self): - """KeyboardInterrupt triggers exit via SIGINT.""" - process = subprocess.run( -@@ -128,6 +129,7 @@ class WindowsSignalTests(unittest.TestCase): - signal.signal(7, handler) - - @unittest.skipUnless(sys.executable, "sys.executable required.") -+ @unittest.skipUnless(sys.stdin.isatty(), "KeyboardInterrupts require a TTY device") - def test_keyboard_interrupt_exit_code(self): - """KeyboardInterrupt triggers an exit using STATUS_CONTROL_C_EXIT.""" - # We don't test via os.kill(os.getpid(), signal.CTRL_C_EVENT) here -@@ -1245,6 +1247,7 @@ class StressTest(unittest.TestCase): - - class RaiseSignalTest(unittest.TestCase): - -+ @unittest.skipUnless(sys.stdin.isatty(), "KeyboardInterrupts require a TTY device") - def test_sigint(self): - with self.assertRaises(KeyboardInterrupt): - signal.raise_signal(signal.SIGINT) -@@ -1279,6 +1279,7 @@ class PidfdSignalTest(unittest.TestCase): - hasattr(signal, "pidfd_send_signal"), - "pidfd support not built in", - ) -+ @unittest.skipUnless(sys.stdin.isatty(), "KeyboardInterrupts require a TTY device") - def test_pidfd_send_signal(self): - with self.assertRaises(OSError) as cm: - signal.pidfd_send_signal(0, signal.SIGINT) -diff --git a/Lib/ctypes/test/test_find.py b/Lib/ctypes/test/test_find.py -index 92ac184..49eec2c 100644 ---- a/Lib/ctypes/test/test_find.py -+++ b/Lib/ctypes/test/test_find.py -@@ -116,6 +116,7 @@ class FindLibraryLinux(unittest.TestCase): - with unittest.mock.patch("ctypes.util._findSoname_ldconfig", lambda *args: None): - self.assertNotEqual(find_library('c'), None) - -+ @unittest.skipIf(True, "This fails for unknown reasons on Guix") - def test_find_library_with_ld(self): - with unittest.mock.patch("ctypes.util._findSoname_ldconfig", lambda *args: None), \ - unittest.mock.patch("ctypes.util._findLib_gcc", lambda *args: None):