* [bug#60240] [PATCH] [WIP] gnu: Add python-3.11.
@ 2022-12-21 15:32 Tanguy Le Carrour
2023-01-06 17:36 ` Simon Tournier
` (6 more replies)
0 siblings, 7 replies; 18+ messages in thread
From: Tanguy Le Carrour @ 2022-12-21 15:32 UTC (permalink / raw)
To: 60240; +Cc: Tanguy Le Carrour
Hi Guix!
I'm currently working on packaging Python 3.11. It seems to produce a
working `python3`, but there's still a lot I have to work on!
I had to copy/paste 3 snippets (see `TODO`) just to modify a few lines in them.
The problem might come from the fact that this package definition
inherits from `python-3.9` that itself inherits from `python-2`.
Might also be because I'm still (really) bad at writing scheme/guile code! ^_^'
This leads me to my first question: wouldn't it be better to write a "fresh"
package definition not inheriting from `python-2` (deprecated since 2020) and
`python-3.9` (soon to be replaced)?
Another question would be: should I first write a package definition for
`python-3.10` so we have it in the history and one could use the time
machine to install it?
Any help or advice would be highly appreciated!
Best regards,
Tanguy
* gnu/packages/python.scm (python-3.11): New variable.
---
.../patches/python-3.11-fix-tests.patch | 418 ++++++++++++++++++
gnu/packages/python.scm | 118 ++++-
2 files changed, 535 insertions(+), 1 deletion(-)
create mode 100644 gnu/packages/patches/python-3.11-fix-tests.patch
diff --git a/gnu/packages/patches/python-3.11-fix-tests.patch b/gnu/packages/patches/python-3.11-fix-tests.patch
new file mode 100644
index 0000000000..f160968a27
--- /dev/null
+++ b/gnu/packages/patches/python-3.11-fix-tests.patch
@@ -0,0 +1,418 @@
+From f0698133e7d6c353a3e6ae0fc62e57ba558a9bc0 Mon Sep 17 00:00:00 2001
+From: Maxim Cournoyer <maxim.cournoyer@gmail.com>
+Date: Wed, 28 Oct 2020 22:55:05 -0400
+Subject: [PATCH] Skip problematic Python 3 tests in Guix.
+
+A subset of the hunks in this patch is tracked upstream at
+https://bugs.python.org/issue38845, which was contributed by Tanguy Le
+Carrour <tanguy@bioneland.org>.
+---
+ Lib/ctypes/test/test_callbacks.py | 3 +++
+ Lib/ctypes/test/test_find.py | 1 +
+ Lib/ctypes/test/test_libc.py | 3 +++
+ Lib/distutils/tests/test_archive_util.py | 2 ++
+ Lib/distutils/tests/test_sdist.py | 1 +
+ Lib/test/_test_multiprocessing.py | 2 ++
+ Lib/test/test_asyncio/test_base_events.py | 2 ++
+ Lib/test/test_generators.py | 1 +
+ Lib/test/test_pathlib.py | 3 +--
+ Lib/test/test_pdb.py | 4 ++--
+ Lib/test/test_regrtest.py | 2 ++
+ Lib/test/test_resource.py | 1 +
+ Lib/test/test_shutil.py | 2 ++
+ Lib/test/test_signal.py | 4 ++++
+ Lib/test/test_socket.py | 8 ++++++++
+ Lib/test/test_spwd.py | 6 ++----
+ Lib/test/test_tarfile.py | 9 ++++++---
+ Lib/test/test_threading.py | 3 +++
+ Lib/test/test_unicodedata.py | 1 +
+ Tools/scripts/run_tests.py | 2 +-
+ 20 files changed, 48 insertions(+), 12 deletions(-)
+
+diff --git a/Lib/ctypes/test/test_callbacks.py b/Lib/ctypes/test/test_callbacks.py
+index d8e9c5a760..94fc5929c9 100644
+--- a/Lib/ctypes/test/test_callbacks.py
++++ b/Lib/ctypes/test/test_callbacks.py
+@@ -5,6 +5,7 @@ from test import support
+ from ctypes import *
+ from ctypes.test import need_symbol
+ import _ctypes_test
++import platform
+
+ class Callbacks(unittest.TestCase):
+ functype = CFUNCTYPE
+@@ -178,6 +179,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_find.py b/Lib/ctypes/test/test_find.py
+index 92ac1840ad..c8eb75dedd 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, "ldconfig is not used 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):
+diff --git a/Lib/ctypes/test/test_libc.py b/Lib/ctypes/test/test_libc.py
+index 56285b5ff8..c088ab3db8 100644
+--- 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
+index e9aad0e40f..8bbaa51ee5 100644
+--- 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
+index 23db126959..6e2329df7d 100644
+--- 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
+index e47905c863..31a5a9c308 100644
+--- a/Lib/test/_test_multiprocessing.py
++++ b/Lib/test/_test_multiprocessing.py
+@@ -1577,6 +1577,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()
+@@ -3905,6 +3906,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_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py
+index 533d5cc7f5..c4f860cc3b 100644
+--- a/Lib/test/test_asyncio/test_base_events.py
++++ b/Lib/test/test_asyncio/test_base_events.py
+@@ -1341,6 +1341,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
+index 3bf1522808..04bac8a7db 100644
+--- a/Lib/test/test_generators.py
++++ b/Lib/test/test_generators.py
+@@ -33,6 +33,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
+index 3da35710b9..5404f9193d 100644
+--- a/Lib/test/test_pathlib.py
++++ b/Lib/test/test_pathlib.py
+@@ -2408,10 +2408,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(sys.platform == "vxworks",
+- "no home directory on VxWorks")
++ @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
+index 8016f81e5a..10190486b4 100644
+--- a/Lib/test/test_pdb.py
++++ b/Lib/test/test_pdb.py
+@@ -1219,11 +1219,11 @@ def test_pdb_issue_20766():
+ > <doctest test.test_pdb.test_pdb_issue_20766[0]>(6)test_function()
+ -> print('pdb %d: %s' % (i, sess._previous_sigint_handler))
+ (Pdb) continue
+- pdb 1: <built-in function default_int_handler>
++ pdb 1: Handlers.SIG_IGN
+ > <doctest test.test_pdb.test_pdb_issue_20766[0]>(6)test_function()
+ -> print('pdb %d: %s' % (i, sess._previous_sigint_handler))
+ (Pdb) continue
+- pdb 2: <built-in function default_int_handler>
++ pdb 2: Handlers.SIG_IGN
+ """
+
+
+diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py
+index a77638b10a..2069b349a8 100644
+--- a/Lib/test/test_regrtest.py
++++ b/Lib/test/test_regrtest.py
+@@ -811,6 +811,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)
+@@ -828,6 +829,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
+index e5ece5284c..5299e54507 100644
+--- a/Lib/test/test_resource.py
++++ b/Lib/test/test_resource.py
+@@ -148,6 +148,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
+index e19af64be0..1b893df6fa 100644
+--- a/Lib/test/test_shutil.py
++++ b/Lib/test/test_shutil.py
+@@ -1427,6 +1427,7 @@ class TestArchives(BaseTest, unittest.TestCase):
+ base_name = os.path.join(tmpdir, 'archive')
+ self.assertRaises(ValueError, make_archive, base_name, 'xxx')
+
++ @unittest.skipIf(True, "The Guix build container has no root user")
+ @support.requires_zlib()
+ def test_make_archive_owner_group(self):
+ # testing make_archive with owner and group, with various combinations
+@@ -1455,6 +1456,7 @@ class TestArchives(BaseTest, unittest.TestCase):
+ self.assertTrue(os.path.isfile(res))
+
+
++ @unittest.skipIf(True, "The Guix build container has no root user")
+ @support.requires_zlib()
+ @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support")
+ def test_tarfile_root_owner(self):
+diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py
+index 45553a6a42..55623f01a3 100644
+--- a/Lib/test/test_signal.py
++++ b/Lib/test/test_signal.py
+@@ -78,7 +78,8 @@ class PosixTests(unittest.TestCase):
+ self.assertLess(len(s), signal.NSIG)
+
+ @unittest.skipUnless(sys.executable, "sys.executable required.")
+ @support.requires_subprocess()
++ @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,7 +129,8 @@ class WindowsSignalTests(unittest.TestCase):
+ signal.signal(7, handler)
+
+ @unittest.skipUnless(sys.executable, "sys.executable required.")
+ @support.requires_subprocess()
++ @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)
+@@ -1275,6 +1278,7 @@ class RaiseSignalTest(unittest.TestCase):
+
+ class PidfdSignalTest(unittest.TestCase):
+
++ @unittest.skipUnless(sys.stdin.isatty(), "KeyboardInterrupts require a TTY device")
+ @unittest.skipUnless(
+ hasattr(signal, "pidfd_send_signal"),
+ "pidfd support not built in",
+diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
+index aefba4f397..6c89f558d5 100755
+--- a/Lib/test/test_socket.py
++++ b/Lib/test/test_socket.py
+@@ -1009,6 +1009,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 [socket_helper.HOSTv4, '10.0.0.1', '255.255.255.255']:
+ self.assertEqual(socket.gethostbyname(addr), addr)
+@@ -1140,6 +1142,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.
+@@ -1489,6 +1493,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)
+@@ -1571,6 +1577,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
+index 07793c84c8..fec672bcbe 100644
+--- 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
+index 29cde91bf7..8d0f20e8bf 100644
+--- a/Lib/test/test_tarfile.py
++++ b/Lib/test/test_tarfile.py
+@@ -2607,9 +2607,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
+index c21cdf8eb7..6c9d575032 100644
+--- a/Lib/test/test_threading.py
++++ b/Lib/test/test_threading.py
+@@ -1398,5 +1398,6 @@ class MiscTestCase(unittest.TestCase):
+ signal.signal(signum, handler)
+
++ @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.
+@@ -1409,6 +1410,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/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py
+index b552d2bd17..28b1144e15 100644
+--- a/Lib/test/test_unicodedata.py
++++ b/Lib/test/test_unicodedata.py
+@@ -309,6 +309,7 @@ class UnicodeMiscTest(UnicodeDatabaseTest):
+ self.assertEqual(len(lines), 1,
+ r"\u%.4x should not be a linebreak" % i)
+
++@requires_resource('network')
+ class NormalizationTest(unittest.TestCase):
+ @staticmethod
+ def check_version(testfile):
+diff --git a/Tools/scripts/run_tests.py b/Tools/scripts/run_tests.py
+index bcfa5e943b..1f2484971b 100644
+--- a/Tools/scripts/run_tests.py
++++ b/Tools/scripts/run_tests.py
+@@ -41,7 +41,7 @@ def main(regrtest_args):
+ else:
+ 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'])
+
+ if cross_compile and hostrunner:
+ # If HOSTRUNNER is set and -p/--python option is not given, then
+--
+2.29.2
+
diff --git a/gnu/packages/python.scm b/gnu/packages/python.scm
index 0c164d7991..4acdbb9feb 100644
--- a/gnu/packages/python.scm
+++ b/gnu/packages/python.scm
@@ -55,7 +55,7 @@
;;; Copyright © 2018, 2019, 2020, 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;; Copyright © 2018 Luther Thompson <lutheroto@gmail.com>
;;; Copyright © 2018 Vagrant Cascadian <vagrant@debian.org>
-;;; Copyright © 2019 Tanguy Le Carrour <tanguy@bioneland.org>
+;;; Copyright © 2019, 2022 Tanguy Le Carrour <tanguy@bioneland.org>
;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;; Copyright © 2020, 2021 Greg Hogan <code@greghogan.com>
;;; Copyright © 2022 Philip McGrath <philip@philipmcgrath.com>
@@ -574,6 +574,122 @@ (define-public python-3.9
(variable "PYTHONTZPATH")
(files (list "share/zoneinfo")))))))
+(define-public python-3.11
+ (package
+ (inherit python-3.9)
+ (name "python")
+ (version "3.11.1")
+ (source (origin
+ (method url-fetch)
+ (uri (string-append "https://www.python.org/ftp/python/" version
+ "/Python-" version ".tar.xz"))
+ (patches (search-patches
+ "python-3-deterministic-build-info.patch"
+ "python-3.11-fix-tests.patch"
+ "python-3-hurd-configure.patch"
+ "python-3-search-paths.patch"))
+ (sha256
+ (base32
+ "13xmvw0pjqr96mr69xxpjkiybwzb95cr14n02v5mdzfgya9931w5"))
+ (modules '((guix build utils)))
+ ;; TODO: how to modify only the first `for-each delete-file`?
+ (snippet '(begin
+ ;; Delete the bundled copy of libexpat.
+ (delete-file-recursively "Modules/expat")
+ (substitute* "Modules/Setup"
+ ;; Link Expat instead of embedding the bundled one.
+ (("^#pyexpat.*")
+ "pyexpat pyexpat.c -lexpat\n"))
+ ;; Suboptimal to delete failing tests here, but if we delete them in
+ ;; the arguments then we need to make sure to strip out that phase
+ ;; when it gets inherited by python and python-minimal.
+ (for-each delete-file
+ '("Lib/test/leakers/test_ctypes.py" ;fails on mips64el
+ "Lib/test/test_pdb.py"
+ "Lib/test/test_shutil.py"
+ "Lib/test/test_socket.py"
+ "Lib/test/test_subprocess.py"
+ "Lib/test/test_tools/test_freeze.py"))
+ ;; Delete windows binaries
+ (for-each delete-file
+ (find-files "Lib/distutils/command"
+ "\\.exe$"))))))
+ (arguments
+ (substitute-keyword-arguments (package-arguments python-3.9)
+ ;; TODO: how to add `--without-static-libpython` without adding everything else?
+ ((#:configure-flags _)
+ `(list "--enable-shared" ;allow embedding
+ "--with-system-expat" ;for XML support
+ "--with-system-ffi" ;build ctypes
+ "--with-ensurepip=install" ;install pip and setuptools
+ "--with-computed-gotos" ;main interpreter loop optimization
+ "--without-static-libpython"
+ "--enable-unicode=ucs4"
+
+ ;; FIXME: These flags makes Python significantly faster, but
+ ;; leads to non-reproducible binaries.
+ ;; "--with-lto" ;increase size by 20MB, but 15% speedup
+ ;; "--enable-optimizations"
+
+ ;; Prevent the installed _sysconfigdata.py from retaining a reference
+ ;; to coreutils.
+ "INSTALL=install -c"
+ "MKDIR_P=mkdir -p"
+
+ ;; Disable runtime check failing if cross-compiling, see:
+ ;; https://lists.yoctoproject.org/pipermail/poky/2013-June/008997.html
+ ,@(if (%current-target-system)
+ '("ac_cv_buggy_getaddrinfo=no" "ac_cv_file__dev_ptmx=no"
+ "ac_cv_file__dev_ptc=no")
+ '())
+ ;; -fno-semantic-interposition reinstates some optimizations by gcc
+ ;; leading to around 15% speedup. This is the default starting from
+ ;; python 3.10.
+ "CFLAGS=-fno-semantic-interposition"
+ (string-append "LDFLAGS=-Wl,-rpath="
+ (assoc-ref %outputs "out") "/lib"
+ " -fno-semantic-interposition")))
+ ((#:phases phases)
+ `(modify-phases ,phases
+ (replace 'check
+ (lambda _
+ (invoke "make" "test")))
+ ;; TODO: fix the original phase instead instead of replacing it.
+ ;; `match-error "match" "no matching pattern" ("python3.11" "python3.9")`
+ (replace 'remove-tests
+ ;; Remove 25 MiB of unneeded unit tests. Keep test_support.*
+ ;; because these files are used by some libraries out there.
+ (lambda* (#:key outputs #:allow-other-keys)
+ (let ((out (assoc-ref outputs "out")))
+ (let ((testdir (string-append out "/lib/python3.11/test")))
+ (with-directory-excursion testdir
+ (for-each delete-file-recursively
+ (scandir testdir
+ (match-lambda
+ ((or "." "..")
+ #f)
+ ("support" #f)
+ (file (not (string-prefix?
+ "test_support." file))))))
+ (call-with-output-file "__init__.py"
+ (const #t))))
+ (let ((libdir (string-append out "/lib/python3.11")))
+ (for-each (lambda (directory)
+ (let ((dir (string-append libdir "/" directory)))
+ (when (file-exists? dir)
+ (delete-file-recursively dir))))
+ '("email/test" "ctypes/test"
+ "unittest/test"
+ "tkinter/test"
+ "sqlite3/test"
+ "bsddb/test"
+ "lib-tk/test"
+ "json/tests"
+ "distutils/tests"))))))))))))
+
+;; Next version.
+(define-public python-next python-3.11)
+
;; Current 3.x version.
(define-public python-3 python-3.9)
--
2.38.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [bug#60240] [PATCH] [WIP] gnu: Add python-3.11.
2022-12-21 15:32 [bug#60240] [PATCH] [WIP] gnu: Add python-3.11 Tanguy Le Carrour
@ 2023-01-06 17:36 ` Simon Tournier
2023-01-09 15:59 ` Tanguy LE CARROUR
2023-03-12 23:35 ` [bug#60240] Python 3.10 in core-updates Andreas Enge
` (5 subsequent siblings)
6 siblings, 1 reply; 18+ messages in thread
From: Simon Tournier @ 2023-01-06 17:36 UTC (permalink / raw)
To: Tanguy Le Carrour, 60240; +Cc: Tanguy Le Carrour
Hi Tanguy,
On Wed, 21 Dec 2022 at 16:32, Tanguy Le Carrour <tanguy@bioneland.org> wrote:
> This leads me to my first question: wouldn't it be better to write a "fresh"
> package definition not inheriting from `python-2` (deprecated since 2020) and
> `python-3.9` (soon to be replaced)?
Yes, it would be nice to have Python 3 as the package definition. And
maybe Python 2 as inheriting from Python 3. :-)
> Another question would be: should I first write a package definition
> for `python-3.10` so we have it in the history and one could use the
> time machine to install it?
Well, it appears to me fine to jump from 3.9 to 3.11 dropping 3.10.
Cheers,
simon
^ permalink raw reply [flat|nested] 18+ messages in thread
* [bug#60240] [PATCH] [WIP] gnu: Add python-3.11.
2023-01-06 17:36 ` Simon Tournier
@ 2023-01-09 15:59 ` Tanguy LE CARROUR
0 siblings, 0 replies; 18+ messages in thread
From: Tanguy LE CARROUR @ 2023-01-09 15:59 UTC (permalink / raw)
To: 60240, Simon Tournier
Hi Simon,
Believe it or not, I sent the patch before I went on vacation and… I kind
of forgot about it! 😅
Quoting Simon Tournier (2023-01-06 18:36:36)
> On Wed, 21 Dec 2022 at 16:32, Tanguy Le Carrour <tanguy@bioneland.org> wrote:
>
> > This leads me to my first question: wouldn't it be better to write a "fresh"
> > package definition not inheriting from `python-2` (deprecated since 2020) and
> > `python-3.9` (soon to be replaced)?
>
> Yes, it would be nice to have Python 3 as the package definition. And
> maybe Python 2 as inheriting from Python 3. :-)
I'm not saying that we should do the same but… Debian is dropping
support for Python 2 in the next release [1].
[1]: https://wiki.debian.org/Python/FAQ#Python_2_support
> > Another question would be: should I first write a package definition
> > for `python-3.10` so we have it in the history and one could use the
> > time machine to install it?
>
> Well, it appears to me fine to jump from 3.9 to 3.11 dropping 3.10.
You know what they say, who can do more can do less! 😁
Regards,
--
Tanguy
^ permalink raw reply [flat|nested] 18+ messages in thread
* [bug#60240] Python 3.10 in core-updates
2022-12-21 15:32 [bug#60240] [PATCH] [WIP] gnu: Add python-3.11 Tanguy Le Carrour
2023-01-06 17:36 ` Simon Tournier
@ 2023-03-12 23:35 ` Andreas Enge
2024-02-19 21:27 ` John Kehayias via Guix-patches via
` (4 subsequent siblings)
6 siblings, 0 replies; 18+ messages in thread
From: Andreas Enge @ 2023-03-12 23:35 UTC (permalink / raw)
To: 60240
Hello Tanguy,
core-updates has Python 3.10.7, so you may wish to base your work on this
branch and submit it once the branch has been merged.
There python@3 still inherits from python2@2. But since it overwrites all
interesting fields, I think it would make sense to write a package definition
"from scratch" by copying fields such as home-page etc.
Good luck with packaging!
Andreas
^ permalink raw reply [flat|nested] 18+ messages in thread
* [bug#60240] Python 3.10 in core-updates
2022-12-21 15:32 [bug#60240] [PATCH] [WIP] gnu: Add python-3.11 Tanguy Le Carrour
2023-01-06 17:36 ` Simon Tournier
2023-03-12 23:35 ` [bug#60240] Python 3.10 in core-updates Andreas Enge
@ 2024-02-19 21:27 ` John Kehayias via Guix-patches via
2024-02-20 14:18 ` Tanguy LE CARROUR
2024-02-21 12:13 ` [bug#60240] [PATCH v2] gnu: Add python-3.12 and python-next Tanguy Le Carrour
` (3 subsequent siblings)
6 siblings, 1 reply; 18+ messages in thread
From: John Kehayias via Guix-patches via @ 2024-02-19 21:27 UTC (permalink / raw)
To: Tanguy LE CARROUR
Cc: Sharlatan Hellseher, Simon Tournier, Munyoki Kilyungi,
Lars-Dominik Braun, 60240, Andreas Enge, jgart, Marius Bakke
Hello,
I was curious about python 3.11 and dug up this issue so I thought I
would check in (CC'ing python-team and original people on the thread).
A link for a refresher: <https://issues.guix.gnu.org/60240>
On Mon, Mar 13, 2023 at 12:35 AM, Andreas Enge wrote:
> Hello Tanguy,
>
> core-updates has Python 3.10.7, so you may wish to base your work on this
> branch and submit it once the branch has been merged.
>
Yes, we have and default to python-3.10 in master but it would be great
to have python-3.11. We could add this as "python-next" and start seeing
what packages can build with 3.11 before deciding if/when to switch
over.
Tanguy: have you tried your patch recently at all? Can we base it off of
3.10 and have a working 3.11 from what you started?
Thanks!
John
> There python@3 still inherits from python2@2. But since it overwrites all
> interesting fields, I think it would make sense to write a package definition
> "from scratch" by copying fields such as home-page etc.
>
> Good luck with packaging!
>
> Andreas
^ permalink raw reply [flat|nested] 18+ messages in thread
* [bug#60240] Python 3.10 in core-updates
2024-02-19 21:27 ` John Kehayias via Guix-patches via
@ 2024-02-20 14:18 ` Tanguy LE CARROUR
0 siblings, 0 replies; 18+ messages in thread
From: Tanguy LE CARROUR @ 2024-02-20 14:18 UTC (permalink / raw)
To: John Kehayias
Cc: Sharlatan Hellseher, Simon Tournier, Munyoki Kilyungi,
Lars-Dominik Braun, 60240, Andreas Enge, jgart, Marius Bakke
Hi John,
Sorry for taking so long to reply, but... I was hiding under my desk...
ashamed to have forgotten this ticket! 😱
Thanks for the reminder!
Quoting John Kehayias (2024-02-19 22:27:48)
> A link for a refresher: <https://issues.guix.gnu.org/60240>
> On Mon, Mar 13, 2023 at 12:35 AM, Andreas Enge wrote:
> > core-updates has Python 3.10.7, so you may wish to base your work on this
> > branch and submit it once the branch has been merged.
I totally missed/forgot-to-answer-to Andreas’ message! **Rude!** 😵
Sooo-sooorry!
> Yes, we have and default to python-3.10 in master but it would be great
> to have python-3.11. We could add this as "python-next" and start seeing
> what packages can build with 3.11 before deciding if/when to switch
> over.
Actually, a year or so after, it would be great to have python-3.12! 😅
> Tanguy: have you tried your patch recently at all? Can we base it off of
> 3.10 and have a working 3.11 from what you started?
… at all! 😅
I’ll try to work on that tomorrow!
--
Tanguy
^ permalink raw reply [flat|nested] 18+ messages in thread
* [bug#60240] [PATCH v2] gnu: Add python-3.12 and python-next.
2022-12-21 15:32 [bug#60240] [PATCH] [WIP] gnu: Add python-3.11 Tanguy Le Carrour
` (2 preceding siblings ...)
2024-02-19 21:27 ` John Kehayias via Guix-patches via
@ 2024-02-21 12:13 ` Tanguy Le Carrour
2024-02-21 18:36 ` Tanguy Le Carrour
2024-02-25 14:08 ` Lars-Dominik Braun
2024-03-06 12:55 ` [bug#60240] [PATCH v3] " Tanguy Le Carrour
` (2 subsequent siblings)
6 siblings, 2 replies; 18+ messages in thread
From: Tanguy Le Carrour @ 2024-02-21 12:13 UTC (permalink / raw)
To: 60240
Cc: john.kehayias, andreas, Tanguy Le Carrour, zimon.toutoune,
Lars-Dominik Braun, Marius Bakke, Munyoki Kilyungi,
Sharlatan Hellseher, jgart
Hi Guix,
Sorry it took me so long —thanks again John for the reminder!—, but I
eventually made it! I have a Python 3.12.2 running on my computer.
I created a brand new package definition for it, not inheriting from
`python-2`. I actually copied/pasted the `python-2` package definition,
removed what was specific to Python 2 and then copied over the things
specific to Python 3 from the `python-3.10` package definition.
There are still things here and there that I’m not happy with, though:
- skipping `test_pdb_issue_20766` doesn’t seem to work, so I modified
the expected output;
- I use the old style for `native-inputs`, for I was not sure how to
make the new style work with a `local-file`;
- I left the `(@ (gnu packages compression) zip)`, even though I’m not
sur why it’s better than "just" `zip`;
- When I apply the patch I get whitespace errors, but I don’t know how
those whitespace were introduced and how to get rid of them.
Btw, the patch targets the branch `python-team`.
Looking forwards to your comments!
* gnu/packages/python.scm (python-3.12, python-next): New variables.
* gnu/packages/patches/python-3.12-fix-tests.patch: New file.
Change-Id: Ie393b732a8863569578e72e62603b75a1655a34e
---
.../patches/python-3.12-fix-tests.patch | 334 ++++++++++++++++
gnu/packages/python.scm | 378 +++++++++++++++++-
2 files changed, 711 insertions(+), 1 deletion(-)
create mode 100644 gnu/packages/patches/python-3.12-fix-tests.patch
diff --git a/gnu/packages/patches/python-3.12-fix-tests.patch b/gnu/packages/patches/python-3.12-fix-tests.patch
new file mode 100644
index 0000000000..206a7223f5
--- /dev/null
+++ b/gnu/packages/patches/python-3.12-fix-tests.patch
@@ -0,0 +1,334 @@
+From f0698133e7d6c353a3e6ae0fc62e57ba558a9bc0 Mon Sep 17 00:00:00 2001
+From: Maxim Cournoyer <maxim.cournoyer@gmail.com>
+Date: Wed, 28 Oct 2020 22:55:05 -0400
+Subject: [PATCH] Skip problematic Python 3 tests in Guix.
+
+A subset of the hunks in this patch is tracked upstream at
+https://bugs.python.org/issue38845, which was contributed by Tanguy Le
+Carrour <tanguy@bioneland.org>.
+
+diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py
+index e42c7ab4bd..8087c84dab 100644
+--- a/Lib/test/_test_multiprocessing.py
++++ b/Lib/test/_test_multiprocessing.py
+@@ -1695,6 +1695,7 @@ def _test_wait_result(cls, c, pid):
+ 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()
+@@ -4150,6 +4151,7 @@ def test_shared_memory_across_processes(self):
+ 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_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py
+index 85c8152d49..e35cfffe84 100644
+--- a/Lib/test/test_asyncio/test_base_events.py
++++ b/Lib/test/test_asyncio/test_base_events.py
+@@ -1377,6 +1377,8 @@ def test_create_connection_no_inet_pton(self, m_socket):
+ 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_ctypes/test_find.py b/Lib/test/test_ctypes/test_find.py
+index a41e94971d..1291af3057 100644
+--- a/Lib/test/test_ctypes/test_find.py
++++ b/Lib/test/test_ctypes/test_find.py
+@@ -117,6 +117,7 @@ def test_find_library_with_gcc(self):
+ with unittest.mock.patch("ctypes.util._findSoname_ldconfig", lambda *args: None):
+ self.assertNotEqual(find_library('c'), None)
+
++ @unittest.skipIf(True, 'Fails 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):
+diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py
+index 1ee9958445..ab6b41befe 100644
+--- a/Lib/test/test_generators.py
++++ b/Lib/test/test_generators.py
+@@ -34,6 +34,7 @@ def generator2(self):
+ 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
+index ec105ae1a0..ae4c5b672e 100644
+--- a/Lib/test/test_pathlib.py
++++ b/Lib/test/test_pathlib.py
+@@ -3069,6 +3069,7 @@ def test_rglob(self):
+ 'pwd module does not expose getpwall()')
+ @unittest.skipIf(sys.platform == "vxworks",
+ "no home directory on VxWorks")
++ @unittest.skipIf(True, "Guix builder home is '/' which causes trouble for these tests")
+ def test_expanduser(self):
+ P = self.cls
+ import_helper.import_module('pwd')
+diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
+index 51b844262e..004d3133cf 100644
+--- a/Lib/test/test_pdb.py
++++ b/Lib/test/test_pdb.py
+@@ -1580,6 +1580,7 @@ def test_pdb_next_command_subiterator():
+ (Pdb) continue
+ """
+
++@unittest.skipIf(True, 'Fails on Guix… but skipIf not taken into account?!')
+ def test_pdb_issue_20766():
+ """Test for reference leaks when the SIGINT handler is set.
+
+@@ -1598,11 +1599,11 @@ def test_pdb_issue_20766():
+ > <doctest test.test_pdb.test_pdb_issue_20766[0]>(6)test_function()
+ -> print('pdb %d: %s' % (i, sess._previous_sigint_handler))
+ (Pdb) continue
+- pdb 1: <built-in function default_int_handler>
++ pdb 1: 1
+ > <doctest test.test_pdb.test_pdb_issue_20766[0]>(6)test_function()
+ -> print('pdb %d: %s' % (i, sess._previous_sigint_handler))
+ (Pdb) continue
+- pdb 2: <built-in function default_int_handler>
++ pdb 2: 1
+ """
+
+ def test_pdb_issue_43318():
+diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py
+index 2ab6f6a986..8cf6b4d1c8 100644
+--- a/Lib/test/test_regrtest.py
++++ b/Lib/test/test_regrtest.py
+@@ -1049,6 +1049,7 @@ def test_fromfile(self):
+ output = self.run_tests('--fromfile', filename)
+ self.check_executed_tests(output, tests, stats=stats)
+
++ @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)
+@@ -1066,6 +1067,7 @@ def test_slowest(self):
+ % (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
+index 317e7ca8f8..7f272daf24 100644
+--- a/Lib/test/test_resource.py
++++ b/Lib/test/test_resource.py
+@@ -151,6 +151,7 @@ def test_freebsd_contants(self):
+
+ @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
+index bf60f37934..5e3a96380a 100644
+--- a/Lib/test/test_shutil.py
++++ b/Lib/test/test_shutil.py
+@@ -1743,6 +1743,7 @@ def test_make_archive(self):
+ base_name = os.path.join(tmpdir, 'archive')
+ self.assertRaises(ValueError, make_archive, base_name, 'xxx')
+
++ @unittest.skipIf(True, "The Guix build container has no root user")
+ @support.requires_zlib()
+ def test_make_archive_owner_group(self):
+ # testing make_archive with owner and group, with various combinations
+@@ -1771,6 +1772,7 @@ def test_make_archive_owner_group(self):
+ self.assertTrue(os.path.isfile(res))
+
+
++ @unittest.skipIf(True, "The Guix build container has no root user")
+ @support.requires_zlib()
+ @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support")
+ def test_tarfile_root_owner(self):
+diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py
+index 637a0ca3b3..2fb804e340 100644
+--- a/Lib/test/test_signal.py
++++ b/Lib/test/test_signal.py
+@@ -160,6 +160,7 @@ def test_valid_signals(self):
+ self.assertLess(signum, signal.NSIG)
+
+ @unittest.skipUnless(sys.executable, "sys.executable required.")
++ @unittest.skipUnless(sys.stdin.isatty(), "KeyboardInterrupts require a TTY device")
+ @support.requires_subprocess()
+ def test_keyboard_interrupt_exit_code(self):
+ """KeyboardInterrupt triggers exit via SIGINT."""
+@@ -211,6 +212,7 @@ def test_issue9324(self):
+ signal.signal(7, handler)
+
+ @unittest.skipUnless(sys.executable, "sys.executable required.")
++ @unittest.skipUnless(sys.stdin.isatty(), "KeyboardInterrupts require a TTY device")
+ @support.requires_subprocess()
+ def test_keyboard_interrupt_exit_code(self):
+ """KeyboardInterrupt triggers an exit using STATUS_CONTROL_C_EXIT."""
+@@ -1407,6 +1409,7 @@ def cycle_handlers():
+
+ 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)
+@@ -1452,6 +1455,7 @@ def __del__(self):
+
+ class PidfdSignalTest(unittest.TestCase):
+
++ @unittest.skipUnless(sys.stdin.isatty(), "KeyboardInterrupts require a TTY device")
+ @unittest.skipUnless(
+ hasattr(signal, "pidfd_send_signal"),
+ "pidfd support not built in",
+diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
+index 4eb5af99d6..9c7b8f6dbc 100644
+--- a/Lib/test/test_socket.py
++++ b/Lib/test/test_socket.py
+@@ -1016,6 +1016,8 @@ def testHostnameRes(self):
+ 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 [socket_helper.HOSTv4, '10.0.0.1', '255.255.255.255']:
+ self.assertEqual(socket.gethostbyname(addr), addr)
+@@ -1161,6 +1163,8 @@ def testNtoHErrors(self):
+ self.assertRaises(OverflowError, socket.ntohl, k)
+ self.assertRaises(OverflowError, socket.htonl, 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.
+@@ -1521,6 +1525,8 @@ def test_sio_loopback_fast_path(self):
+ 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)
+@@ -1653,6 +1659,8 @@ def test_getnameinfo(self):
+ # 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
+index 50766c2548..0c7eb7a83a 100644
+--- a/Lib/test/test_spwd.py
++++ b/Lib/test/test_spwd.py
+@@ -9,8 +9,7 @@
+ spwd = import_helper.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):
+@@ -60,8 +59,7 @@ def test_getspnam(self):
+ 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
+index 71489ea493..33351919fe 100644
+--- a/Lib/test/test_tarfile.py
++++ b/Lib/test/test_tarfile.py
+@@ -2911,9 +2911,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
+index 00d9e591c7..2515603715 100644
+--- a/Lib/test/test_threading.py
++++ b/Lib/test/test_threading.py
+@@ -1962,6 +1962,7 @@ def check_interrupt_main_noerror(self, signum):
+ # Restore original handler
+ signal.signal(signum, handler)
+
++ @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.
+@@ -1973,6 +1974,8 @@ def call_interrupt():
+ 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/Lib/test/test_tools/test_freeze.py b/Lib/test/test_tools/test_freeze.py
+index 0e7ed67de7..6539a2983b 100644
+--- a/Lib/test/test_tools/test_freeze.py
++++ b/Lib/test/test_tools/test_freeze.py
+@@ -23,6 +23,7 @@
+ 'test is too slow with PGO')
+ class TestFreeze(unittest.TestCase):
+
++ @unittest.skipIf(True, 'Fails on Guix.')
+ @support.requires_resource('cpu') # Building Python is slow
+ def test_freeze_simple_script(self):
+ script = textwrap.dedent("""
+diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py
+index 515c3840cb..a96dfad0fe 100644
+--- a/Lib/test/test_unicodedata.py
++++ b/Lib/test/test_unicodedata.py
+@@ -342,6 +342,7 @@ def test_linebreak_7643(self):
+ self.assertEqual(len(lines), 1,
+ r"\u%.4x should not be a linebreak" % i)
+
++@requires_resource('network')
+ class NormalizationTest(unittest.TestCase):
+ @staticmethod
+ def check_version(testfile):
+diff --git a/Tools/scripts/run_tests.py b/Tools/scripts/run_tests.py
+index 445a34ae3e..8f750537c3 100644
+--- a/Tools/scripts/run_tests.py
++++ b/Tools/scripts/run_tests.py
+@@ -69,7 +69,7 @@ def main(regrtest_args):
+ else:
+ 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'])
+
+ if cross_compile and hostrunner:
+ # If HOSTRUNNER is set and -p/--python option is not given, then
diff --git a/gnu/packages/python.scm b/gnu/packages/python.scm
index 51d5f598d7..471cf190fb 100644
--- a/gnu/packages/python.scm
+++ b/gnu/packages/python.scm
@@ -55,7 +55,7 @@
;;; Copyright © 2018, 2019, 2020, 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;; Copyright © 2018 Luther Thompson <lutheroto@gmail.com>
;;; Copyright © 2018 Vagrant Cascadian <vagrant@debian.org>
-;;; Copyright © 2019 Tanguy Le Carrour <tanguy@bioneland.org>
+;;; Copyright © 2019, 2024 Tanguy Le Carrour <tanguy@bioneland.org>
;;; Copyright © 2020, 2023 Janneke Nieuwenhuizen <janneke@gnu.org>
;;; Copyright © 2020, 2021 Greg Hogan <code@greghogan.com>
;;; Copyright © 2022 Philip McGrath <philip@philipmcgrath.com>
@@ -596,6 +596,382 @@ (define-public python-3.10
(variable "PYTHONTZPATH")
(files (list "share/zoneinfo")))))))
+(define-public python-3.12
+ (package
+ (name "python")
+ (version "3.12.2")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (string-append "https://www.python.org/ftp/python/" version
+ "/Python-" version ".tar.xz"))
+ (sha256
+ (base32 "0w6qyfhc912xxav9x9pifwca40b4l49vy52wai9j0gc1mhni2a5y"))
+ (patches (search-patches "python-3-deterministic-build-info.patch"
+ "python-3.12-fix-tests.patch"
+ "python-3-hurd-configure.patch"))
+ (modules '((guix build utils)))
+ (snippet '(begin
+ ;; Delete the bundled copy of libexpat.
+ (delete-file-recursively "Modules/expat")
+ (substitute* "Modules/Setup"
+ ;; Link Expat instead of embedding the bundled one.
+ (("^#pyexpat.*")
+ "pyexpat pyexpat.c -lexpat\n"))
+ ;; Delete windows binaries
+ (for-each delete-file
+ (find-files "Lib/distutils/command" "\\.exe$"))))))
+ (outputs '("out" "tk" ;tkinter; adds 50 MiB to the closure
+ "idle")) ;programming environment; weighs 5MB
+ (build-system gnu-build-system)
+ (arguments
+ `(#:test-target "test"
+ #:configure-flags (list "--enable-shared" ;allow embedding
+ "--with-system-expat" ;for XML support
+ "--with-system-ffi" ;build ctypes
+ "--with-ensurepip=install" ;install pip and setuptools
+ "--with-computed-gotos" ;main interpreter loop optimization
+ "--enable-unicode=ucs4"
+ "--without-static-libpython"
+
+ ;; FIXME: These flags makes Python significantly faster, but
+ ;; leads to non-reproducible binaries.
+ ;; "--with-lto" ;increase size by 20MB, but 15% speedup
+ ;; "--enable-optimizations"
+
+ ;; Prevent the installed _sysconfigdata.py from retaining a reference
+ ;; to coreutils.
+ "INSTALL=install -c"
+ "MKDIR_P=mkdir -p"
+
+ ;; Disable runtime check failing if cross-compiling, see:
+ ;; https://lists.yoctoproject.org/pipermail/poky/2013-June/008997.html
+ ,@(if (%current-target-system)
+ '("ac_cv_buggy_getaddrinfo=no"
+ "ac_cv_file__dev_ptmx=no"
+ "ac_cv_file__dev_ptc=no")
+ '())
+ ;; -fno-semantic-interposition reinstates some optimizations by gcc
+ ;; leading to around 15% speedup. This is the default starting from
+ ;; python 3.10.
+ "CFLAGS=-fno-semantic-interposition"
+ (string-append "LDFLAGS=-Wl,-rpath="
+ (assoc-ref %outputs "out")
+ "/lib"
+ " -fno-semantic-interposition"))
+ ;; With no -j argument tests use all available cpus, so provide one.
+ #:make-flags (list (string-append (format #f "TESTOPTS=-j~d"
+ (parallel-job-count))
+ ;; those tests fail on low-memory systems
+ " --exclude test_mmap test_socket test_threading test_asyncio"
+ ,@(if (system-hurd?)
+ '(" test_posix" ;multiple errors
+ " test_time"
+ " test_pty"
+ " test_shutil"
+ " test_tempfile" ;chflags: invalid argument:
+ ;; tbv14c9t/dir0/dir0/dir0/test0.txt
+ " test_os" ;stty: 'standard input':
+ ;; Inappropriate ioctl for device
+ " test_openpty" ;No such file or directory
+ " test_selectors" ;assertEqual(NUM_FDS // 2, len(fds))
+ ;; 32752 != 4
+ " test_compileall" ;multiple errors
+ " test_poll" ;list index out of range
+ " test_subprocess" ;runs over 10min
+ " test_asyncore" ;multiple errors
+ " test_threadsignals"
+ " test_eintr" ;Process return code is -14
+ " test_io" ;multiple errors
+ " test_logging"
+ " test_signal"
+ " test_flags" ;ERROR
+ " test_bidirectional_pty"
+ " test_create_unix_connection"
+ " test_unix_sock_client_ops"
+ " test_open_unix_connection"
+ " test_open_unix_connection_error"
+ " test_read_pty_output"
+ " test_write_pty"
+ " test_concurrent_futures" ;freeze
+ " test_venv" ;freeze
+ " test_multiprocessing_forkserver" ;runs over 10min
+ " test_multiprocessing_spawn" ;runs over 10min
+ " test_builtin"
+ " test_capi"
+ " test_dbm_ndbm"
+ " test_exceptions"
+ " test_faulthandler"
+ " test_getopt"
+ " test_importlib"
+ " test_json"
+ " test_multiprocessing_fork"
+ " test_multiprocessing_main_handling"
+ " test_pdb "
+ " test_regrtest"
+ " test_sqlite")
+ '())))
+
+ #:modules ((ice-9 ftw)
+ (ice-9 match)
+ (guix build utils)
+ (guix build gnu-build-system))
+
+ #:phases (modify-phases %standard-phases
+ ,@(if (system-hurd?)
+ `((add-after 'unpack
+ 'disable-multi-processing
+ (lambda _
+ (substitute* "Makefile.pre.in"
+ (("-j0")
+ "-j1")))))
+ '())
+ (add-before 'configure 'patch-lib-shells
+ (lambda _
+ ;; This variable is used in setup.py to enable cross compilation
+ ;; specific switches. As it is not set properly by configure
+ ;; script, set it manually.
+ ,@(if (%current-target-system)
+ '((setenv "_PYTHON_HOST_PLATFORM" ""))
+ '())
+ ;; Filter for existing files, since some may not exist in all
+ ;; versions of python that are built with this recipe.
+ (substitute* (filter file-exists?
+ '("Lib/subprocess.py"
+ "Lib/popen2.py"
+ "Lib/distutils/tests/test_spawn.py"
+ "Lib/test/support/__init__.py"
+ "Lib/test/test_subprocess.py"))
+ (("/bin/sh")
+ (which "sh")))))
+ (add-before 'configure 'do-not-record-configure-flags
+ (lambda* (#:key configure-flags #:allow-other-keys)
+ ;; Remove configure flags from the installed '_sysconfigdata.py'
+ ;; and 'Makefile' so we don't end up keeping references to the
+ ;; build tools.
+ ;;
+ ;; Preserve at least '--with-system-ffi' since otherwise the
+ ;; thing tries to build libffi, fails, and we end up with a
+ ;; Python that lacks ctypes.
+ (substitute* "configure"
+ (("^CONFIG_ARGS=.*$")
+ (format #f "CONFIG_ARGS='~a'\n"
+ (if (member "--with-system-ffi"
+ configure-flags)
+ "--with-system-ffi" ""))))))
+ (add-before 'check 'pre-check
+ (lambda _
+ ;; 'Lib/test/test_site.py' needs a valid $HOME
+ (setenv "HOME"
+ (getcwd))))
+ (add-after 'unpack 'set-source-file-times-to-1980
+ ;; XXX One of the tests uses a ZIP library to pack up some of the
+ ;; source tree, and fails with "ZIP does not support timestamps
+ ;; before 1980". Work around this by setting the file times in the
+ ;; source tree to sometime in early 1980.
+ (lambda _
+ (let ((circa-1980 (* 10 366 24 60 60)))
+ (ftw "."
+ (lambda (file stat flag)
+ (utime file circa-1980 circa-1980) #t)))))
+ (add-after 'unpack 'remove-windows-binaries
+ (lambda _
+ ;; Delete .exe from embedded .whl (zip) files
+ (for-each (lambda (whl)
+ (let ((dir "whl-content")
+ (circa-1980 (* 10 366 24 60 60)))
+ (mkdir-p dir)
+ (with-directory-excursion dir
+ (let ((whl (string-append "../" whl)))
+ (invoke "unzip" whl)
+ (for-each delete-file
+ (find-files "." "\\.exe$"))
+ (delete-file whl)
+ ;; Reset timestamps to prevent them from ending
+ ;; up in the Zip archive.
+ (ftw "."
+ (lambda (file stat flag)
+ (utime file circa-1980
+ circa-1980) #t))
+ (apply invoke "zip" "-X" whl
+ (find-files "."
+ #:directories? #t))))
+ (delete-file-recursively dir)))
+ (find-files "Lib/ensurepip" "\\.whl$"))))
+ (add-after 'install 'remove-tests
+ ;; Remove 25 MiB of unneeded unit tests. Keep test_support.*
+ ;; because these files are used by some libraries out there.
+ (lambda* (#:key outputs #:allow-other-keys)
+ (let ((out (assoc-ref outputs "out")))
+ (match (scandir (string-append out "/lib")
+ (lambda (name)
+ (string-prefix? "python" name)))
+ ((pythonX.Y)
+ (let ((testdir (string-append out "/lib/" pythonX.Y
+ "/test")))
+ (with-directory-excursion testdir
+ (for-each delete-file-recursively
+ (scandir testdir
+ (match-lambda
+ ((or "." "..")
+ #f)
+ ("support" #f)
+ (file (not (string-prefix?
+ "test_support."
+ file))))))
+ (call-with-output-file "__init__.py"
+ (const #t))))
+ (let ((libdir (string-append out "/lib/" pythonX.Y)))
+ (for-each (lambda (directory)
+ (let ((dir (string-append libdir "/"
+ directory)))
+ (when (file-exists? dir)
+ (delete-file-recursively dir))))
+ '("email/test" "ctypes/test"
+ "unittest/test"
+ "tkinter/test"
+ "sqlite3/test"
+ "bsddb/test"
+ "lib-tk/test"
+ "json/tests"
+ "distutils/tests"))))))))
+ (add-after 'remove-tests 'move-tk-inter
+ (lambda* (#:key outputs #:allow-other-keys)
+ ;; When Tkinter support is built move it to a separate output so
+ ;; that the main output doesn't contain a reference to Tcl/Tk.
+ (let ((out (assoc-ref outputs "out"))
+ (tk (assoc-ref outputs "tk")))
+ (when tk
+ (match (find-files out "tkinter.*\\.so")
+ ((tkinter.so)
+ ;; The .so is in OUT/lib/pythonX.Y/lib-dynload, but we
+ ;; want it under TK/lib/pythonX.Y/site-packages.
+ (let* ((len (string-length out))
+ (target (string-append tk "/"
+ (string-drop (dirname
+ (dirname
+ tkinter.so))
+ len)
+ "/site-packages")))
+ (install-file tkinter.so target)
+ (delete-file tkinter.so))))))))
+ (add-after 'move-tk-inter 'move-idle
+ (lambda* (#:key outputs #:allow-other-keys)
+ ;; when idle is built, move it to a separate output to save some
+ ;; space (5MB)
+ (let ((out (assoc-ref outputs "out"))
+ (idle (assoc-ref outputs "idle")))
+ (when idle
+ (for-each (lambda (file)
+ (let ((target (string-append idle
+ "/bin/"
+ (basename
+ file))))
+ (install-file file
+ (dirname target))
+ (delete-file file)))
+ (find-files (string-append out "/bin")
+ "^idle"))
+ (match (find-files out "^idlelib$"
+ #:directories? #t)
+ ((idlelib)
+ (let* ((len (string-length out))
+ (target (string-append idle "/"
+ (string-drop
+ idlelib len)
+ "/site-packages")))
+ (mkdir-p (dirname target))
+ (rename-file idlelib target))))))))
+ (add-after 'move-idle 'rebuild-bytecode
+ (lambda* (#:key outputs #:allow-other-keys)
+ (let ((out (assoc-ref outputs "out")))
+ ;; Disable hash randomization to ensure the generated .pycs
+ ;; are reproducible.
+ (setenv "PYTHONHASHSEED" "0")
+
+ (for-each (lambda (output)
+ ;; XXX: Delete existing pycs generated by the build
+ ;; system beforehand because the -f argument does
+ ;; not necessarily overwrite all files, leading to
+ ;; indeterministic results.
+ (for-each (lambda (pyc)
+ (delete-file pyc))
+ (find-files output "\\.pyc$"))
+
+ (apply invoke
+ `(,,(if (%current-target-system)
+ "python3"
+ '(string-append out
+ "/bin/python3")) "-m"
+ "compileall"
+ "-o"
+ "0"
+ "-o"
+ "1"
+ "-o"
+ "2"
+ "-f" ;force rebuild
+ "--invalidation-mode=unchecked-hash"
+ ;; Don't build lib2to3, because it's
+ ;; Python 2 code.
+ "-x"
+ "lib2to3/.*"
+ ,output)))
+ (map cdr outputs)))))
+ (add-before 'check 'set-TZDIR
+ (lambda* (#:key inputs native-inputs #:allow-other-keys)
+ ;; test_email requires the Olson time zone database.
+ (setenv "TZDIR"
+ (string-append (assoc-ref (or native-inputs
+ inputs) "tzdata")
+ "/share/zoneinfo"))))
+ (add-after 'install 'install-sitecustomize.py
+ ,(customize-site version)))))
+ (inputs (list bzip2
+ expat
+ gdbm
+ libffi ;for ctypes
+ sqlite ;for sqlite extension
+ openssl
+ readline
+ zlib
+ tcl
+ tk)) ;for tkinter
+ (native-inputs `(("tzdata" ,tzdata-for-tests)
+ ("unzip" ,unzip)
+ ("zip" ,(@ (gnu packages compression) zip))
+ ("pkg-config" ,pkg-config)
+ ("sitecustomize.py" ,(local-file (search-auxiliary-file
+ "python/sitecustomize.py")))
+ ;; When cross-compiling, a native version of Python itself is needed.
+ ,@(if (%current-target-system)
+ `(("python" ,this-package)
+ ("which" ,which))
+ '())))
+ (native-search-paths
+ (list (guix-pythonpath-search-path version)
+ ;; Used to locate tzdata by the zoneinfo module introduced in
+ ;; Python 3.9.
+ (search-path-specification
+ (variable "PYTHONTZPATH")
+ (files (list "share/zoneinfo")))))
+ (home-page "https://www.python.org")
+ (synopsis "High-level, dynamically-typed programming language")
+ (description
+ "Python is a remarkably powerful dynamic programming language that
+is used in a wide variety of application domains. Some of its key
+distinguishing features include: clear, readable syntax; strong
+introspection capabilities; intuitive object orientation; natural
+expression of procedural code; full modularity, supporting hierarchical
+packages; exception-based error handling; and very high level dynamic
+data types.")
+ (properties '((cpe-name . "python")))
+ (license license:psfl)))
+
+
+;; Next 3.x version.
+(define-public python-next python-3.12)
+
;; Current 3.x version.
(define-public python-3 python-3.10)
base-commit: 6831dfc58bf14341176f7358941ed685f34fb4c3
--
2.41.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [bug#60240] [PATCH v2] gnu: Add python-3.12 and python-next.
2024-02-21 12:13 ` [bug#60240] [PATCH v2] gnu: Add python-3.12 and python-next Tanguy Le Carrour
@ 2024-02-21 18:36 ` Tanguy Le Carrour
2024-02-22 9:07 ` Tanguy LE CARROUR
2024-02-25 14:08 ` Lars-Dominik Braun
1 sibling, 1 reply; 18+ messages in thread
From: Tanguy Le Carrour @ 2024-02-21 18:36 UTC (permalink / raw)
To: 60240; +Cc: john.kehayias, andreas, zimon.toutoune
Oups! I've just figured out that I forgot to mention something…
Le 21 février 2024 13:13:42 GMT+01:00, Tanguy Le Carrour <tanguy@bioneland.org> a écrit :
>+ ;; With no -j argument tests use all available cpus, so provide one.
>+ #:make-flags (list (string-append (format #f "TESTOPTS=-j~d"
>+ (parallel-job-count))
>+ ;; those tests fail on low-memory systems
>+ " --exclude test_mmap test_socket test_threading test_asyncio"
>+ ,@(if (system-hurd?)
>+ '(" test_posix" ;multiple errors
>+ ;;...
>+ " test_sqlite")
>+ '())))
Here, I had to exlude 'test_socket' and 'test_threading' for, after 20min, there were making my computer crash! 😱
They were in the "if hurd" block, so I removed them from there.
I'll try to un-exclude them and see if it works on my bigger computer at work.
--
Tanguy
^ permalink raw reply [flat|nested] 18+ messages in thread
* [bug#60240] [PATCH v2] gnu: Add python-3.12 and python-next.
2024-02-21 18:36 ` Tanguy Le Carrour
@ 2024-02-22 9:07 ` Tanguy LE CARROUR
0 siblings, 0 replies; 18+ messages in thread
From: Tanguy LE CARROUR @ 2024-02-22 9:07 UTC (permalink / raw)
To: 60240; +Cc: john.kehayias, andreas, zimon.toutoune
Quoting Tanguy Le Carrour (2024-02-21 19:36:35)
> Le 21 février 2024 13:13:42 GMT+01:00, Tanguy Le Carrour <tanguy@bioneland.org> a écrit :
> >+ ;; With no -j argument tests use all available cpus, so provide one.
> >+ #:make-flags (list (string-append (format #f "TESTOPTS=-j~d"
> >+ (parallel-job-count))
> >+ ;; those tests fail on low-memory systems
> >+ " --exclude test_mmap test_socket test_threading test_asyncio"
> >+ ,@(if (system-hurd?)
> >+ '(" test_posix" ;multiple errors
> >+ ;;...
> >+ " test_sqlite")
> >+ '())))
>
> Here, I had to exlude 'test_socket' and 'test_threading' for, after 20min, there were making my computer crash! 😱
> They were in the "if hurd" block, so I removed them from there.
>
> I'll try to un-exclude them and see if it works on my bigger computer at work.
And… it almost killed my computer… again! 😱
So, I won’t "un-exclude" them, and I’ll leave the patch as it is.
--
Tanguy
^ permalink raw reply [flat|nested] 18+ messages in thread
* [bug#60240] [PATCH v2] gnu: Add python-3.12 and python-next.
2024-02-21 12:13 ` [bug#60240] [PATCH v2] gnu: Add python-3.12 and python-next Tanguy Le Carrour
2024-02-21 18:36 ` Tanguy Le Carrour
@ 2024-02-25 14:08 ` Lars-Dominik Braun
2024-02-26 8:25 ` Tanguy LE CARROUR
1 sibling, 1 reply; 18+ messages in thread
From: Lars-Dominik Braun @ 2024-02-25 14:08 UTC (permalink / raw)
To: Tanguy Le Carrour
Cc: Sharlatan Hellseher, zimon.toutoune, Munyoki Kilyungi, 60240,
andreas, jgart, Marius Bakke, john.kehayias
Hi,
> I created a brand new package definition for it, not inheriting from
> `python-2`. I actually copied/pasted the `python-2` package definition,
> removed what was specific to Python 2 and then copied over the things
> specific to Python 3 from the `python-3.10` package definition.
LGTM.
I believe the separate tk output does not give us any benefits regarding
closure size (any more?), because tcl and tk are both referenced from
`out`. Can we remove those references to reduce closure size again?
And I can also confirm test_asyncio runs out of memory on my machine
and test_threading never finishes. We should probably investigate both,
because they should not.
> - When I apply the patch I get whitespace errors, but I don’t know how
> those whitespace were introduced and how to get rid of them.
Line 641, as highlighted by `git show`.
> Btw, the patch targets the branch `python-team`.
I believe this change could target master, since it only adds python-3.12,
but does not cause any rebuilds using it.
Cheers,
Lars
^ permalink raw reply [flat|nested] 18+ messages in thread
* [bug#60240] [PATCH v2] gnu: Add python-3.12 and python-next.
2024-02-25 14:08 ` Lars-Dominik Braun
@ 2024-02-26 8:25 ` Tanguy LE CARROUR
2024-03-02 9:59 ` Lars-Dominik Braun
0 siblings, 1 reply; 18+ messages in thread
From: Tanguy LE CARROUR @ 2024-02-26 8:25 UTC (permalink / raw)
To: Lars-Dominik Braun; +Cc: 60240
Hi Lars,
Thanks for reviewing!
Quoting Lars-Dominik Braun (2024-02-25 15:08:20)
> > I created a brand new package definition for it, not inheriting from
> > `python-2`. I actually copied/pasted the `python-2` package definition,
> > removed what was specific to Python 2 and then copied over the things
> > specific to Python 3 from the `python-3.10` package definition.
>
> LGTM.
>
> I believe the separate tk output does not give us any benefits regarding
> closure size (any more?), because tcl and tk are both referenced from
> `out`. Can we remove those references to reduce closure size again?
Sorry, but I’m not sure to see what you mean!?
Outputs are defined for `out`, `tk` and `idle`. And I see phases to move
files to the outputs: `move-tk-inter` and `move-idle`.
What do you mean by `referenced from out`? And how would you remove such
a reference!
Sorry, I’m still new to this! 😅
> And I can also confirm test_asyncio runs out of memory on my machine
> and test_threading never finishes. We should probably investigate both,
> because they should not.
I searched in the issue list on GH, but couldn’t find anything relevant.
But there are quite a lot of issues there.
Do we have to fix this before we merge it?
> > - When I apply the patch I get whitespace errors, but I don’t know how
> > those whitespace were introduced and how to get rid of them.
>
> Line 641, as highlighted by `git show`.
Mmm… when I apply it using b4, it doesn’t complain any more?! 🤔
```console
$ b4 shazam 20221221153230.27764-1-tanguy@bioneland.org
Looking up https://yhetil.org/guix/20221221153230.27764-1-tanguy@bioneland.org
Grabbing thread from yhetil.org/guix/20221221153230.27764-1-tanguy@bioneland.org/t.mbox.gz
Checking for newer revisions
Grabbing search results from lore.kernel.org
Nothing matching that query.
Analyzing 10 messages in the thread
Will use the latest revision: v2
You can pick other revisions using the -vN flag
---
[PATCH v2] gnu: Add python-3.12 and python-next.
---
Total patches: 1
---
Base: using specified base-commit 6831dfc58bf14341176f7358941ed685f34fb4c3
Applying: gnu: Add python-3.12 and python-next.
```
> > Btw, the patch targets the branch `python-team`.
>
> I believe this change could target master, since it only adds python-3.12,
> but does not cause any rebuilds using it.
Oh… correct! 😅
Regards,
--
Tanguy
^ permalink raw reply [flat|nested] 18+ messages in thread
* [bug#60240] [PATCH v2] gnu: Add python-3.12 and python-next.
2024-02-26 8:25 ` Tanguy LE CARROUR
@ 2024-03-02 9:59 ` Lars-Dominik Braun
2024-03-06 12:49 ` Tanguy LE CARROUR
0 siblings, 1 reply; 18+ messages in thread
From: Lars-Dominik Braun @ 2024-03-02 9:59 UTC (permalink / raw)
To: Tanguy LE CARROUR; +Cc: 60240
[-- Attachment #1: Type: text/plain, Size: 1792 bytes --]
Hey,
> Sorry, but I’m not sure to see what you mean!?
> Outputs are defined for `out`, `tk` and `idle`. And I see phases to move
> files to the outputs: `move-tk-inter` and `move-idle`.
>
> What do you mean by `referenced from out`? And how would you remove such
> a reference!
so, if you look at `guix size python@3.12`, you can see
it lists tk and tcl. And then a `grep -Ri /gnu/store/path/to/tcl
/gnu/store/path/to/python` reveals it’s being referenced by
lib/python3.12/_sysconfigdata__linux_x86_64-linux-gnu.py and
lib/python3.12/config-3.12-x86_64-linux-gnu/Makefile, which are both
part of the default “out” output. That means TCL and TK are both
part of the closure of the python@3.12 package, i.e. they are downloaded
whenever you install it, making the package “bigger” in size (234.5
MiB in total to be precise). I believe we wanted to avoid that by moving
some parts of Python into the separate “tk” output. But apparently
that does not work (any more).
The attached patch (on top of yours) removes these references and shrinks
the closure of python@3.12 to 180.6 MiB. But I don’t know whether it
has any negative side-effects (i.e. packages not building any more),
because I can’t build libxslt with Python 3.12 due to the module
“imp” having been removed in Python 3.12.
> I searched in the issue list on GH, but couldn’t find anything relevant.
> But there are quite a lot of issues there.
> Do we have to fix this before we merge it?
No, we’d have to dig deeper into which particular test causes this
behavior.
And actually one more nitpick: The name of the package should be
“python-next” not “python”, otherwise `guix install python`
will pick Python 3.12 (it’s based on the name property, not the
variable name).
Cheers,
Lars
[-- Attachment #2: python-3.12-remove-tk-tcl-refs.patch --]
[-- Type: text/plain, Size: 1901 bytes --]
diff --git a/gnu/packages/python.scm b/gnu/packages/python.scm
index 471cf190fb..0b887a2cdb 100644
--- a/gnu/packages/python.scm
+++ b/gnu/packages/python.scm
@@ -836,7 +836,7 @@ (define-public python-3.12
"json/tests"
"distutils/tests"))))))))
(add-after 'remove-tests 'move-tk-inter
- (lambda* (#:key outputs #:allow-other-keys)
+ (lambda* (#:key outputs inputs #:allow-other-keys)
;; When Tkinter support is built move it to a separate output so
;; that the main output doesn't contain a reference to Tcl/Tk.
(let ((out (assoc-ref outputs "out"))
@@ -854,7 +854,14 @@ (define-public python-3.12
len)
"/site-packages")))
(install-file tkinter.so target)
- (delete-file tkinter.so))))))))
+ (delete-file tkinter.so))))
+ ;; Remove explicit store path references.
+ (let ((tcl (assoc-ref inputs "tcl"))
+ (tk (assoc-ref inputs "tk")))
+ (substitute* (find-files (string-append out "/lib")
+ "^(_sysconfigdata_.*\\.py|Makefile)$")
+ (((string-append "-L" tk "/lib")) "")
+ (((string-append "-L" tcl "/lib")) "")))))))
(add-after 'move-tk-inter 'move-idle
(lambda* (#:key outputs #:allow-other-keys)
;; when idle is built, move it to a separate output to save some
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [bug#60240] [PATCH v2] gnu: Add python-3.12 and python-next.
2024-03-02 9:59 ` Lars-Dominik Braun
@ 2024-03-06 12:49 ` Tanguy LE CARROUR
0 siblings, 0 replies; 18+ messages in thread
From: Tanguy LE CARROUR @ 2024-03-06 12:49 UTC (permalink / raw)
To: Lars-Dominik Braun; +Cc: 60240
Hi Lars,
Quoting Lars-Dominik Braun (2024-03-02 10:59:23)
> And actually one more nitpick: The name of the package should be
> “python-next” not “python”, otherwise `guix install python`
> will pick Python 3.12 (it’s based on the name property, not the
> variable name).
Oh… thanks! Fixed in v3.
The package name only apply when used I input, right?
I submitted other patches where I did the same. But it’s a different matter
for Python libraries, I guess!? 🤔
> > Sorry, but I’m not sure to see what you mean!?
> > Outputs are defined for `out`, `tk` and `idle`. And I see phases to move
> > files to the outputs: `move-tk-inter` and `move-idle`.
> >
> > What do you mean by `referenced from out`? And how would you remove such
> > a reference!
>
> so, if you look at `guix size python@3.12`, you can see
> it lists tk and tcl. And then a `grep -Ri /gnu/store/path/to/tcl
> /gnu/store/path/to/python` reveals it’s being referenced by
> lib/python3.12/_sysconfigdata__linux_x86_64-linux-gnu.py and
> lib/python3.12/config-3.12-x86_64-linux-gnu/Makefile, which are both
> part of the default “out” output. That means TCL and TK are both
> part of the closure of the python@3.12 package, i.e. they are downloaded
> whenever you install it, making the package “bigger” in size (234.5
> MiB in total to be precise). I believe we wanted to avoid that by moving
> some parts of Python into the separate “tk” output. But apparently
> that does not work (any more).
> The attached patch (on top of yours) removes these references and shrinks
> the closure of python@3.12 to 180.6 MiB.
Oh-again! Thanks for taking the time to clarify!
I think I now see what you see:
```console
$ ./pre-inst-env guix size python-next
store item total self
/gnu/store/g6w91736w66pszrg0bmcgwx84ahw7frd-python-next-3.12.2 180.6 82.3 45.6%
/gnu/store/gsjczqir1wbz8p770zndrpw4rnppmxi3-glibc-2.35 40.6 38.8 21.5%
/gnu/store/930nwsiysdvy2x5zv1sf6v7ym75z8ayk-gcc-11.3.0-lib 75.3 34.7 19.2%
/gnu/store/69wd3pd1hd3j84xr965jj2fk2qmxn0hl-openssl-3.0.8 83.4 8.1 4.5%
/gnu/store/bcc053jvsbspdjr17gnnd9dg85b3a0gy-ncurses-6.2.20210619 81.2 5.9 3.3%
/gnu/store/4jakqiibsvrkv4jdw1wyl6racrwv9bkh-sqlite-3.39.3 86.0 3.4 1.9%
/gnu/store/zzyywykw7kriln18rxqd82f0k5kidla7-bash-static-5.1.16 1.8 1.8 1.0%
/gnu/store/lxfc2a05ysi7vlaq0m3w5wsfsy0drdlw-readline-8.1.2 82.6 1.4 0.8%
/gnu/store/6k1yys9wqrfn4y41ic1win8gpnimncwj-xz-5.2.8 77.7 1.4 0.8%
/gnu/store/rib9g2ig1xf3kclyl076w28parmncg4k-bash-minimal-5.1.16 41.6 1.0 0.6%
/gnu/store/2w976k6g70gkfih9wwhalqsni209vcqz-gdbm-1.23 75.9 0.6 0.4%
/gnu/store/pl09vk5g3cl8fxfln2hjk996pyahqk8m-bzip2-1.0.8 76.7 0.4 0.2%
/gnu/store/fw1wywd34vh33l4dq182ds5d7jdz45j5-expat-2.5.0 75.7 0.4 0.2%
/gnu/store/slzq3zqwj75lbrg4ly51hfhbv2vhryv5-zlib-1.2.13 75.5 0.2 0.1%
/gnu/store/w8b0l8hk6g0fahj4fvmc4qqm3cvaxnmv-libffi-3.4.4 75.5 0.2 0.1%
total: 180.6 MiB
```
No more Tcl/Tk, thanks! 👍
If you don’t mind, I squashed your modification in v3.
> But I don’t know whether it has any negative side-effects (i.e.
> packages not building any more), because I can’t build libxslt with
> Python 3.12 due to the module “imp” having been removed in Python
> 3.12.
Mmmm… is it something that has to be fixed in `libxslt`?
More likely, it comes from `python-lxml`. Our current version is 4.9.1,
and one test file (`src/lxml/html/tests/test_html5parser.py`) depends on
`imp` for `imp.new_module`.
This has been dropped in 5.1.0.
Regards,
--
Tanguy
^ permalink raw reply [flat|nested] 18+ messages in thread
* [bug#60240] [PATCH v3] gnu: Add python-3.12 and python-next.
2022-12-21 15:32 [bug#60240] [PATCH] [WIP] gnu: Add python-3.11 Tanguy Le Carrour
` (3 preceding siblings ...)
2024-02-21 12:13 ` [bug#60240] [PATCH v2] gnu: Add python-3.12 and python-next Tanguy Le Carrour
@ 2024-03-06 12:55 ` Tanguy Le Carrour
2024-03-07 18:45 ` [bug#60240] [PATCH v4] " Tanguy Le Carrour
2024-03-07 18:58 ` [bug#60240] [PATCH v5] " Tanguy Le Carrour
6 siblings, 0 replies; 18+ messages in thread
From: Tanguy Le Carrour @ 2024-03-06 12:55 UTC (permalink / raw)
To: 60240
Cc: Tanguy Le Carrour, Lars-Dominik Braun, Lars-Dominik Braun,
Marius Bakke, Munyoki Kilyungi, Sharlatan Hellseher, jgart
Patch v3 changes the name of the package to `python-next` and
actually exclude Tcl/Tk from `out`. Thanks Lars!
* gnu/packages/python.scm (python-3.12, python-next): New variables.
* gnu/packages/patches/python-3.12-fix-tests.patch: New file.
Change-Id: Ie393b732a8863569578e72e62603b75a1655a34e
---
.../patches/python-3.12-fix-tests.patch | 334 +++++++++++++++
gnu/packages/python.scm | 385 +++++++++++++++++-
2 files changed, 718 insertions(+), 1 deletion(-)
create mode 100644 gnu/packages/patches/python-3.12-fix-tests.patch
diff --git a/gnu/packages/patches/python-3.12-fix-tests.patch b/gnu/packages/patches/python-3.12-fix-tests.patch
new file mode 100644
index 0000000000..fa5c8027ce
--- /dev/null
+++ b/gnu/packages/patches/python-3.12-fix-tests.patch
@@ -0,0 +1,334 @@
+From f0698133e7d6c353a3e6ae0fc62e57ba558a9bc0 Mon Sep 17 00:00:00 2001
+From: Maxim Cournoyer <maxim.cournoyer@gmail.com>
+Date: Wed, 28 Oct 2020 22:55:05 -0400
+Subject: [PATCH] Skip problematic Python 3 tests in Guix.
+
+A subset of the hunks in this patch is tracked upstream at
+https://bugs.python.org/issue38845, which was contributed by Tanguy Le
+Carrour <tanguy@bioneland.org>.
+
+diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py
+index e42c7ab4bd..8087c84dab 100644
+--- a/Lib/test/_test_multiprocessing.py
++++ b/Lib/test/_test_multiprocessing.py
+@@ -1695,6 +1695,7 @@ def _test_wait_result(cls, c, pid):
+ 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()
+@@ -4150,6 +4151,7 @@ def test_shared_memory_across_processes(self):
+ 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_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py
+index 85c8152d49..e35cfffe84 100644
+--- a/Lib/test/test_asyncio/test_base_events.py
++++ b/Lib/test/test_asyncio/test_base_events.py
+@@ -1377,6 +1377,8 @@ def test_create_connection_no_inet_pton(self, m_socket):
+ 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_ctypes/test_find.py b/Lib/test/test_ctypes/test_find.py
+index a41e94971d..1291af3057 100644
+--- a/Lib/test/test_ctypes/test_find.py
++++ b/Lib/test/test_ctypes/test_find.py
+@@ -117,6 +117,7 @@ def test_find_library_with_gcc(self):
+ with unittest.mock.patch("ctypes.util._findSoname_ldconfig", lambda *args: None):
+ self.assertNotEqual(find_library('c'), None)
+
++ @unittest.skipIf(True, 'Fails 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):
+diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py
+index 1ee9958445..ab6b41befe 100644
+--- a/Lib/test/test_generators.py
++++ b/Lib/test/test_generators.py
+@@ -34,6 +34,7 @@ def generator2(self):
+ 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
+index ec105ae1a0..ae4c5b672e 100644
+--- a/Lib/test/test_pathlib.py
++++ b/Lib/test/test_pathlib.py
+@@ -3069,6 +3069,7 @@ def test_rglob(self):
+ 'pwd module does not expose getpwall()')
+ @unittest.skipIf(sys.platform == "vxworks",
+ "no home directory on VxWorks")
++ @unittest.skipIf(True, "Guix builder home is '/' which causes trouble for these tests")
+ def test_expanduser(self):
+ P = self.cls
+ import_helper.import_module('pwd')
+diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
+index 51b844262e..004d3133cf 100644
+--- a/Lib/test/test_pdb.py
++++ b/Lib/test/test_pdb.py
+@@ -1580,6 +1580,7 @@ def test_pdb_next_command_subiterator():
+ (Pdb) continue
+ """
+
++@unittest.skipIf(True, 'Fails on Guix… but skipIf not taken into account?!')
+ def test_pdb_issue_20766():
+ """Test for reference leaks when the SIGINT handler is set.
+
+@@ -1598,11 +1599,11 @@ def test_pdb_issue_20766():
+ > <doctest test.test_pdb.test_pdb_issue_20766[0]>(6)test_function()
+ -> print('pdb %d: %s' % (i, sess._previous_sigint_handler))
+ (Pdb) continue
+- pdb 1: <built-in function default_int_handler>
++ pdb 1: 1
+ > <doctest test.test_pdb.test_pdb_issue_20766[0]>(6)test_function()
+ -> print('pdb %d: %s' % (i, sess._previous_sigint_handler))
+ (Pdb) continue
+- pdb 2: <built-in function default_int_handler>
++ pdb 2: 1
+ """
+
+ def test_pdb_issue_43318():
+diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py
+index 2ab6f6a986..8cf6b4d1c8 100644
+--- a/Lib/test/test_regrtest.py
++++ b/Lib/test/test_regrtest.py
+@@ -1049,6 +1049,7 @@ def test_fromfile(self):
+ output = self.run_tests('--fromfile', filename)
+ self.check_executed_tests(output, tests, stats=stats)
+
++ @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)
+@@ -1066,6 +1067,7 @@ def test_slowest(self):
+ % (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
+index 317e7ca8f8..7f272daf24 100644
+--- a/Lib/test/test_resource.py
++++ b/Lib/test/test_resource.py
+@@ -151,6 +151,7 @@ def test_freebsd_contants(self):
+
+ @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
+index bf60f37934..5e3a96380a 100644
+--- a/Lib/test/test_shutil.py
++++ b/Lib/test/test_shutil.py
+@@ -1743,6 +1743,7 @@ def test_make_archive(self):
+ base_name = os.path.join(tmpdir, 'archive')
+ self.assertRaises(ValueError, make_archive, base_name, 'xxx')
+
++ @unittest.skipIf(True, "The Guix build container has no root user")
+ @support.requires_zlib()
+ def test_make_archive_owner_group(self):
+ # testing make_archive with owner and group, with various combinations
+@@ -1771,6 +1772,7 @@ def test_make_archive_owner_group(self):
+ self.assertTrue(os.path.isfile(res))
+
+
++ @unittest.skipIf(True, "The Guix build container has no root user")
+ @support.requires_zlib()
+ @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support")
+ def test_tarfile_root_owner(self):
+diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py
+index 637a0ca3b3..2fb804e340 100644
+--- a/Lib/test/test_signal.py
++++ b/Lib/test/test_signal.py
+@@ -160,6 +160,7 @@ def test_valid_signals(self):
+ self.assertLess(signum, signal.NSIG)
+
+ @unittest.skipUnless(sys.executable, "sys.executable required.")
++ @unittest.skipUnless(sys.stdin.isatty(), "KeyboardInterrupts require a TTY device")
+ @support.requires_subprocess()
+ def test_keyboard_interrupt_exit_code(self):
+ """KeyboardInterrupt triggers exit via SIGINT."""
+@@ -211,6 +212,7 @@ def test_issue9324(self):
+ signal.signal(7, handler)
+
+ @unittest.skipUnless(sys.executable, "sys.executable required.")
++ @unittest.skipUnless(sys.stdin.isatty(), "KeyboardInterrupts require a TTY device")
+ @support.requires_subprocess()
+ def test_keyboard_interrupt_exit_code(self):
+ """KeyboardInterrupt triggers an exit using STATUS_CONTROL_C_EXIT."""
+@@ -1407,6 +1409,7 @@ def cycle_handlers():
+
+ 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)
+@@ -1452,6 +1455,7 @@ def __del__(self):
+
+ class PidfdSignalTest(unittest.TestCase):
+
++ @unittest.skipUnless(sys.stdin.isatty(), "KeyboardInterrupts require a TTY device")
+ @unittest.skipUnless(
+ hasattr(signal, "pidfd_send_signal"),
+ "pidfd support not built in",
+diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
+index 4eb5af99d6..9c7b8f6dbc 100644
+--- a/Lib/test/test_socket.py
++++ b/Lib/test/test_socket.py
+@@ -1016,6 +1016,8 @@ def testHostnameRes(self):
+ 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 [socket_helper.HOSTv4, '10.0.0.1', '255.255.255.255']:
+ self.assertEqual(socket.gethostbyname(addr), addr)
+@@ -1161,6 +1163,8 @@ def testNtoHErrors(self):
+ self.assertRaises(OverflowError, socket.ntohl, k)
+ self.assertRaises(OverflowError, socket.htonl, 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.
+@@ -1521,6 +1525,8 @@ def test_sio_loopback_fast_path(self):
+ 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)
+@@ -1653,6 +1659,8 @@ def test_getnameinfo(self):
+ # 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
+index 50766c2548..0c7eb7a83a 100644
+--- a/Lib/test/test_spwd.py
++++ b/Lib/test/test_spwd.py
+@@ -9,8 +9,7 @@
+ spwd = import_helper.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):
+@@ -60,8 +59,7 @@ def test_getspnam(self):
+ 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
+index 71489ea493..33351919fe 100644
+--- a/Lib/test/test_tarfile.py
++++ b/Lib/test/test_tarfile.py
+@@ -2911,9 +2911,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
+index 00d9e591c7..2515603715 100644
+--- a/Lib/test/test_threading.py
++++ b/Lib/test/test_threading.py
+@@ -1962,6 +1962,7 @@ def check_interrupt_main_noerror(self, signum):
+ # Restore original handler
+ signal.signal(signum, handler)
+
++ @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.
+@@ -1973,6 +1974,8 @@ def call_interrupt():
+ 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/Lib/test/test_tools/test_freeze.py b/Lib/test/test_tools/test_freeze.py
+index 0e7ed67de7..6539a2983b 100644
+--- a/Lib/test/test_tools/test_freeze.py
++++ b/Lib/test/test_tools/test_freeze.py
+@@ -23,6 +23,7 @@
+ 'test is too slow with PGO')
+ class TestFreeze(unittest.TestCase):
+
++ @unittest.skipIf(True, 'Fails on Guix.')
+ @support.requires_resource('cpu') # Building Python is slow
+ def test_freeze_simple_script(self):
+ script = textwrap.dedent("""
+diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py
+index 515c3840cb..a96dfad0fe 100644
+--- a/Lib/test/test_unicodedata.py
++++ b/Lib/test/test_unicodedata.py
+@@ -342,6 +342,7 @@ def test_linebreak_7643(self):
+ self.assertEqual(len(lines), 1,
+ r"\u%.4x should not be a linebreak" % i)
+
++@requires_resource('network')
+ class NormalizationTest(unittest.TestCase):
+ @staticmethod
+ def check_version(testfile):
+diff --git a/Tools/scripts/run_tests.py b/Tools/scripts/run_tests.py
+index 445a34ae3e..8f750537c3 100644
+--- a/Tools/scripts/run_tests.py
++++ b/Tools/scripts/run_tests.py
+@@ -69,7 +69,7 @@ def main(regrtest_args):
+ else:
+ 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'])
+
+ if cross_compile and hostrunner:
+ # If HOSTRUNNER is set and -p/--python option is not given, then
diff --git a/gnu/packages/python.scm b/gnu/packages/python.scm
index 51d5f598d7..25fe83ea69 100644
--- a/gnu/packages/python.scm
+++ b/gnu/packages/python.scm
@@ -55,7 +55,7 @@
;;; Copyright © 2018, 2019, 2020, 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;; Copyright © 2018 Luther Thompson <lutheroto@gmail.com>
;;; Copyright © 2018 Vagrant Cascadian <vagrant@debian.org>
-;;; Copyright © 2019 Tanguy Le Carrour <tanguy@bioneland.org>
+;;; Copyright © 2019, 2024 Tanguy Le Carrour <tanguy@bioneland.org>
;;; Copyright © 2020, 2023 Janneke Nieuwenhuizen <janneke@gnu.org>
;;; Copyright © 2020, 2021 Greg Hogan <code@greghogan.com>
;;; Copyright © 2022 Philip McGrath <philip@philipmcgrath.com>
@@ -596,6 +596,389 @@ (define-public python-3.10
(variable "PYTHONTZPATH")
(files (list "share/zoneinfo")))))))
+(define-public python-3.12
+ (package
+ (name "python-next")
+ (version "3.12.2")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (string-append "https://www.python.org/ftp/python/" version
+ "/Python-" version ".tar.xz"))
+ (sha256
+ (base32 "0w6qyfhc912xxav9x9pifwca40b4l49vy52wai9j0gc1mhni2a5y"))
+ (patches (search-patches "python-3-deterministic-build-info.patch"
+ "python-3.12-fix-tests.patch"
+ "python-3-hurd-configure.patch"))
+ (modules '((guix build utils)))
+ (snippet '(begin
+ ;; Delete the bundled copy of libexpat.
+ (delete-file-recursively "Modules/expat")
+ (substitute* "Modules/Setup"
+ ;; Link Expat instead of embedding the bundled one.
+ (("^#pyexpat.*")
+ "pyexpat pyexpat.c -lexpat\n"))
+ ;; Delete windows binaries
+ (for-each delete-file
+ (find-files "Lib/distutils/command" "\\.exe$"))))))
+ (outputs '("out" "tk" ;tkinter; adds 50 MiB to the closure
+ "idle")) ;programming environment; weighs 5MB
+ (build-system gnu-build-system)
+ (arguments
+ `(#:test-target "test"
+ #:configure-flags (list "--enable-shared" ;allow embedding
+ "--with-system-expat" ;for XML support
+ "--with-system-ffi" ;build ctypes
+ "--with-ensurepip=install" ;install pip and setuptools
+ "--with-computed-gotos" ;main interpreter loop optimization
+ "--enable-unicode=ucs4"
+ "--without-static-libpython"
+
+ ;; FIXME: These flags makes Python significantly faster, but
+ ;; leads to non-reproducible binaries.
+ ;; "--with-lto" ;increase size by 20MB, but 15% speedup
+ ;; "--enable-optimizations"
+
+ ;; Prevent the installed _sysconfigdata.py from retaining a reference
+ ;; to coreutils.
+ "INSTALL=install -c"
+ "MKDIR_P=mkdir -p"
+
+ ;; Disable runtime check failing if cross-compiling, see:
+ ;; https://lists.yoctoproject.org/pipermail/poky/2013-June/008997.html
+ ,@(if (%current-target-system)
+ '("ac_cv_buggy_getaddrinfo=no"
+ "ac_cv_file__dev_ptmx=no"
+ "ac_cv_file__dev_ptc=no")
+ '())
+ ;; -fno-semantic-interposition reinstates some optimizations by gcc
+ ;; leading to around 15% speedup. This is the default starting from
+ ;; python 3.10.
+ "CFLAGS=-fno-semantic-interposition"
+ (string-append "LDFLAGS=-Wl,-rpath="
+ (assoc-ref %outputs "out")
+ "/lib"
+ " -fno-semantic-interposition"))
+ ;; With no -j argument tests use all available cpus, so provide one.
+ #:make-flags (list (string-append (format #f "TESTOPTS=-j~d"
+ (parallel-job-count))
+ ;; those tests fail on low-memory systems
+ " --exclude test_mmap test_socket test_threading test_asyncio"
+ ,@(if (system-hurd?)
+ '(" test_posix" ;multiple errors
+ " test_time"
+ " test_pty"
+ " test_shutil"
+ " test_tempfile" ;chflags: invalid argument:
+ ;; tbv14c9t/dir0/dir0/dir0/test0.txt
+ " test_os" ;stty: 'standard input':
+ ;; Inappropriate ioctl for device
+ " test_openpty" ;No such file or directory
+ " test_selectors" ;assertEqual(NUM_FDS // 2, len(fds))
+ ;; 32752 != 4
+ " test_compileall" ;multiple errors
+ " test_poll" ;list index out of range
+ " test_subprocess" ;runs over 10min
+ " test_asyncore" ;multiple errors
+ " test_threadsignals"
+ " test_eintr" ;Process return code is -14
+ " test_io" ;multiple errors
+ " test_logging"
+ " test_signal"
+ " test_flags" ;ERROR
+ " test_bidirectional_pty"
+ " test_create_unix_connection"
+ " test_unix_sock_client_ops"
+ " test_open_unix_connection"
+ " test_open_unix_connection_error"
+ " test_read_pty_output"
+ " test_write_pty"
+ " test_concurrent_futures" ;freeze
+ " test_venv" ;freeze
+ " test_multiprocessing_forkserver" ;runs over 10min
+ " test_multiprocessing_spawn" ;runs over 10min
+ " test_builtin"
+ " test_capi"
+ " test_dbm_ndbm"
+ " test_exceptions"
+ " test_faulthandler"
+ " test_getopt"
+ " test_importlib"
+ " test_json"
+ " test_multiprocessing_fork"
+ " test_multiprocessing_main_handling"
+ " test_pdb "
+ " test_regrtest"
+ " test_sqlite")
+ '())))
+
+ #:modules ((ice-9 ftw)
+ (ice-9 match)
+ (guix build utils)
+ (guix build gnu-build-system))
+
+ #:phases (modify-phases %standard-phases
+ ,@(if (system-hurd?)
+ `((add-after 'unpack
+ 'disable-multi-processing
+ (lambda _
+ (substitute* "Makefile.pre.in"
+ (("-j0")
+ "-j1")))))
+ '())
+ (add-before 'configure 'patch-lib-shells
+ (lambda _
+ ;; This variable is used in setup.py to enable cross compilation
+ ;; specific switches. As it is not set properly by configure
+ ;; script, set it manually.
+ ,@(if (%current-target-system)
+ '((setenv "_PYTHON_HOST_PLATFORM" ""))
+ '())
+ ;; Filter for existing files, since some may not exist in all
+ ;; versions of python that are built with this recipe.
+ (substitute* (filter file-exists?
+ '("Lib/subprocess.py"
+ "Lib/popen2.py"
+ "Lib/distutils/tests/test_spawn.py"
+ "Lib/test/support/__init__.py"
+ "Lib/test/test_subprocess.py"))
+ (("/bin/sh")
+ (which "sh")))))
+ (add-before 'configure 'do-not-record-configure-flags
+ (lambda* (#:key configure-flags #:allow-other-keys)
+ ;; Remove configure flags from the installed '_sysconfigdata.py'
+ ;; and 'Makefile' so we don't end up keeping references to the
+ ;; build tools.
+ ;;
+ ;; Preserve at least '--with-system-ffi' since otherwise the
+ ;; thing tries to build libffi, fails, and we end up with a
+ ;; Python that lacks ctypes.
+ (substitute* "configure"
+ (("^CONFIG_ARGS=.*$")
+ (format #f "CONFIG_ARGS='~a'\n"
+ (if (member "--with-system-ffi"
+ configure-flags)
+ "--with-system-ffi" ""))))))
+ (add-before 'check 'pre-check
+ (lambda _
+ ;; 'Lib/test/test_site.py' needs a valid $HOME
+ (setenv "HOME"
+ (getcwd))))
+ (add-after 'unpack 'set-source-file-times-to-1980
+ ;; XXX One of the tests uses a ZIP library to pack up some of the
+ ;; source tree, and fails with "ZIP does not support timestamps
+ ;; before 1980". Work around this by setting the file times in the
+ ;; source tree to sometime in early 1980.
+ (lambda _
+ (let ((circa-1980 (* 10 366 24 60 60)))
+ (ftw "."
+ (lambda (file stat flag)
+ (utime file circa-1980 circa-1980) #t)))))
+ (add-after 'unpack 'remove-windows-binaries
+ (lambda _
+ ;; Delete .exe from embedded .whl (zip) files
+ (for-each (lambda (whl)
+ (let ((dir "whl-content")
+ (circa-1980 (* 10 366 24 60 60)))
+ (mkdir-p dir)
+ (with-directory-excursion dir
+ (let ((whl (string-append "../" whl)))
+ (invoke "unzip" whl)
+ (for-each delete-file
+ (find-files "." "\\.exe$"))
+ (delete-file whl)
+ ;; Reset timestamps to prevent them from ending
+ ;; up in the Zip archive.
+ (ftw "."
+ (lambda (file stat flag)
+ (utime file circa-1980
+ circa-1980) #t))
+ (apply invoke "zip" "-X" whl
+ (find-files "."
+ #:directories? #t))))
+ (delete-file-recursively dir)))
+ (find-files "Lib/ensurepip" "\\.whl$"))))
+ (add-after 'install 'remove-tests
+ ;; Remove 25 MiB of unneeded unit tests. Keep test_support.*
+ ;; because these files are used by some libraries out there.
+ (lambda* (#:key outputs #:allow-other-keys)
+ (let ((out (assoc-ref outputs "out")))
+ (match (scandir (string-append out "/lib")
+ (lambda (name)
+ (string-prefix? "python" name)))
+ ((pythonX.Y)
+ (let ((testdir (string-append out "/lib/" pythonX.Y
+ "/test")))
+ (with-directory-excursion testdir
+ (for-each delete-file-recursively
+ (scandir testdir
+ (match-lambda
+ ((or "." "..")
+ #f)
+ ("support" #f)
+ (file (not (string-prefix?
+ "test_support."
+ file))))))
+ (call-with-output-file "__init__.py"
+ (const #t))))
+ (let ((libdir (string-append out "/lib/" pythonX.Y)))
+ (for-each (lambda (directory)
+ (let ((dir (string-append libdir "/"
+ directory)))
+ (when (file-exists? dir)
+ (delete-file-recursively dir))))
+ '("email/test" "ctypes/test"
+ "unittest/test"
+ "tkinter/test"
+ "sqlite3/test"
+ "bsddb/test"
+ "lib-tk/test"
+ "json/tests"
+ "distutils/tests"))))))))
+ (add-after 'remove-tests 'move-tk-inter
+ (lambda* (#:key outputs inputs #:allow-other-keys)
+ ;; When Tkinter support is built move it to a separate output so
+ ;; that the main output doesn't contain a reference to Tcl/Tk.
+ (let ((out (assoc-ref outputs "out"))
+ (tk (assoc-ref outputs "tk")))
+ (when tk
+ (match (find-files out "tkinter.*\\.so")
+ ((tkinter.so)
+ ;; The .so is in OUT/lib/pythonX.Y/lib-dynload, but we
+ ;; want it under TK/lib/pythonX.Y/site-packages.
+ (let* ((len (string-length out))
+ (target (string-append tk "/"
+ (string-drop (dirname
+ (dirname
+ tkinter.so))
+ len)
+ "/site-packages")))
+ (install-file tkinter.so target)
+ (delete-file tkinter.so))))
+ ;; Remove explicit store path references.
+ (let ((tcl (assoc-ref inputs "tcl"))
+ (tk (assoc-ref inputs "tk")))
+ (substitute* (find-files (string-append out "/lib")
+ "^(_sysconfigdata_.*\\.py|Makefile)$")
+ (((string-append "-L" tk "/lib")) "")
+ (((string-append "-L" tcl "/lib")) "")))))))
+ (add-after 'move-tk-inter 'move-idle
+ (lambda* (#:key outputs #:allow-other-keys)
+ ;; when idle is built, move it to a separate output to save some
+ ;; space (5MB)
+ (let ((out (assoc-ref outputs "out"))
+ (idle (assoc-ref outputs "idle")))
+ (when idle
+ (for-each (lambda (file)
+ (let ((target (string-append idle
+ "/bin/"
+ (basename
+ file))))
+ (install-file file
+ (dirname target))
+ (delete-file file)))
+ (find-files (string-append out "/bin")
+ "^idle"))
+ (match (find-files out "^idlelib$"
+ #:directories? #t)
+ ((idlelib)
+ (let* ((len (string-length out))
+ (target (string-append idle "/"
+ (string-drop
+ idlelib len)
+ "/site-packages")))
+ (mkdir-p (dirname target))
+ (rename-file idlelib target))))))))
+ (add-after 'move-idle 'rebuild-bytecode
+ (lambda* (#:key outputs #:allow-other-keys)
+ (let ((out (assoc-ref outputs "out")))
+ ;; Disable hash randomization to ensure the generated .pycs
+ ;; are reproducible.
+ (setenv "PYTHONHASHSEED" "0")
+
+ (for-each (lambda (output)
+ ;; XXX: Delete existing pycs generated by the build
+ ;; system beforehand because the -f argument does
+ ;; not necessarily overwrite all files, leading to
+ ;; indeterministic results.
+ (for-each (lambda (pyc)
+ (delete-file pyc))
+ (find-files output "\\.pyc$"))
+
+ (apply invoke
+ `(,,(if (%current-target-system)
+ "python3"
+ '(string-append out
+ "/bin/python3")) "-m"
+ "compileall"
+ "-o"
+ "0"
+ "-o"
+ "1"
+ "-o"
+ "2"
+ "-f" ;force rebuild
+ "--invalidation-mode=unchecked-hash"
+ ;; Don't build lib2to3, because it's
+ ;; Python 2 code.
+ "-x"
+ "lib2to3/.*"
+ ,output)))
+ (map cdr outputs)))))
+ (add-before 'check 'set-TZDIR
+ (lambda* (#:key inputs native-inputs #:allow-other-keys)
+ ;; test_email requires the Olson time zone database.
+ (setenv "TZDIR"
+ (string-append (assoc-ref (or native-inputs
+ inputs) "tzdata")
+ "/share/zoneinfo"))))
+ (add-after 'install 'install-sitecustomize.py
+ ,(customize-site version)))))
+ (inputs (list bzip2
+ expat
+ gdbm
+ libffi ;for ctypes
+ sqlite ;for sqlite extension
+ openssl
+ readline
+ zlib
+ tcl
+ tk)) ;for tkinter
+ (native-inputs `(("tzdata" ,tzdata-for-tests)
+ ("unzip" ,unzip)
+ ("zip" ,(@ (gnu packages compression) zip))
+ ("pkg-config" ,pkg-config)
+ ("sitecustomize.py" ,(local-file (search-auxiliary-file
+ "python/sitecustomize.py")))
+ ;; When cross-compiling, a native version of Python itself is needed.
+ ,@(if (%current-target-system)
+ `(("python" ,this-package)
+ ("which" ,which))
+ '())))
+ (native-search-paths
+ (list (guix-pythonpath-search-path version)
+ ;; Used to locate tzdata by the zoneinfo module introduced in
+ ;; Python 3.9.
+ (search-path-specification
+ (variable "PYTHONTZPATH")
+ (files (list "share/zoneinfo")))))
+ (home-page "https://www.python.org")
+ (synopsis "High-level, dynamically-typed programming language")
+ (description
+ "Python is a remarkably powerful dynamic programming language that
+is used in a wide variety of application domains. Some of its key
+distinguishing features include: clear, readable syntax; strong
+introspection capabilities; intuitive object orientation; natural
+expression of procedural code; full modularity, supporting hierarchical
+packages; exception-based error handling; and very high level dynamic
+data types.")
+ (properties '((cpe-name . "python")))
+ (license license:psfl)))
+
+
+;; Next 3.x version.
+(define-public python-next python-3.12)
+
;; Current 3.x version.
(define-public python-3 python-3.10)
base-commit: f3ea06baca2b96cd20170616fd5da13ec2daac54
--
2.41.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [bug#60240] [PATCH v4] gnu: Add python-3.12 and python-next.
2022-12-21 15:32 [bug#60240] [PATCH] [WIP] gnu: Add python-3.11 Tanguy Le Carrour
` (4 preceding siblings ...)
2024-03-06 12:55 ` [bug#60240] [PATCH v3] " Tanguy Le Carrour
@ 2024-03-07 18:45 ` Tanguy Le Carrour
2024-03-07 18:58 ` [bug#60240] [PATCH v5] " Tanguy Le Carrour
6 siblings, 0 replies; 18+ messages in thread
From: Tanguy Le Carrour @ 2024-03-07 18:45 UTC (permalink / raw)
To: 60240
Cc: Tanguy Le Carrour, Lars-Dominik Braun, Lars-Dominik Braun,
Marius Bakke, Munyoki Kilyungi, Sharlatan Hellseher, jgart
Thanks to public shaming during the patch review session 😅,
I’m sending this v4 that fixes some linter warnings.
Most of them were "line too long" that I wrongly thought
were taken care of by `guix style`. My bad!
The remaining problems are:
```
gnu/packages/python.scm:600:2: python-next@3.12.2: file names of patches should start with the package name
```
But I think the naming follows the convention used for other Python patches.
```
gnu/packages/python.scm:648:0: python-next@3.12.2: line 648 is way too long (101 characters)
```
It’s an URL that I cannot split.
```
gnu/packages/python.scm:604:5: python-next@3.12.2: updater 'generic-html' failed to find upstream releases
```
Don’t know what that means.
```
gnu/packages/python.scm:604:5: python-next@3.12.2: source not archived on Software Heritage and missing from the Disarchive database
```
Not **yet** archived by SWH.
* gnu/packages/python.scm (python-3.12, python-next): New variables.
* gnu/packages/patches/python-3.12-fix-tests.patch: New file.
Change-Id: Ie393b732a8863569578e72e62603b75a1655a34e
Signed-off-by: Tanguy Le Carrour <tanguy@bioneland.org>
---
.../patches/python-3.12-fix-tests.patch | 334 +++++++++++++++
gnu/packages/python.scm | 385 +++++++++++++++++-
2 files changed, 718 insertions(+), 1 deletion(-)
create mode 100644 gnu/packages/patches/python-3.12-fix-tests.patch
diff --git a/gnu/packages/patches/python-3.12-fix-tests.patch b/gnu/packages/patches/python-3.12-fix-tests.patch
new file mode 100644
index 0000000000..fa5c8027ce
--- /dev/null
+++ b/gnu/packages/patches/python-3.12-fix-tests.patch
@@ -0,0 +1,334 @@
+From f0698133e7d6c353a3e6ae0fc62e57ba558a9bc0 Mon Sep 17 00:00:00 2001
+From: Maxim Cournoyer <maxim.cournoyer@gmail.com>
+Date: Wed, 28 Oct 2020 22:55:05 -0400
+Subject: [PATCH] Skip problematic Python 3 tests in Guix.
+
+A subset of the hunks in this patch is tracked upstream at
+https://bugs.python.org/issue38845, which was contributed by Tanguy Le
+Carrour <tanguy@bioneland.org>.
+
+diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py
+index e42c7ab4bd..8087c84dab 100644
+--- a/Lib/test/_test_multiprocessing.py
++++ b/Lib/test/_test_multiprocessing.py
+@@ -1695,6 +1695,7 @@ def _test_wait_result(cls, c, pid):
+ 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()
+@@ -4150,6 +4151,7 @@ def test_shared_memory_across_processes(self):
+ 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_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py
+index 85c8152d49..e35cfffe84 100644
+--- a/Lib/test/test_asyncio/test_base_events.py
++++ b/Lib/test/test_asyncio/test_base_events.py
+@@ -1377,6 +1377,8 @@ def test_create_connection_no_inet_pton(self, m_socket):
+ 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_ctypes/test_find.py b/Lib/test/test_ctypes/test_find.py
+index a41e94971d..1291af3057 100644
+--- a/Lib/test/test_ctypes/test_find.py
++++ b/Lib/test/test_ctypes/test_find.py
+@@ -117,6 +117,7 @@ def test_find_library_with_gcc(self):
+ with unittest.mock.patch("ctypes.util._findSoname_ldconfig", lambda *args: None):
+ self.assertNotEqual(find_library('c'), None)
+
++ @unittest.skipIf(True, 'Fails 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):
+diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py
+index 1ee9958445..ab6b41befe 100644
+--- a/Lib/test/test_generators.py
++++ b/Lib/test/test_generators.py
+@@ -34,6 +34,7 @@ def generator2(self):
+ 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
+index ec105ae1a0..ae4c5b672e 100644
+--- a/Lib/test/test_pathlib.py
++++ b/Lib/test/test_pathlib.py
+@@ -3069,6 +3069,7 @@ def test_rglob(self):
+ 'pwd module does not expose getpwall()')
+ @unittest.skipIf(sys.platform == "vxworks",
+ "no home directory on VxWorks")
++ @unittest.skipIf(True, "Guix builder home is '/' which causes trouble for these tests")
+ def test_expanduser(self):
+ P = self.cls
+ import_helper.import_module('pwd')
+diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
+index 51b844262e..004d3133cf 100644
+--- a/Lib/test/test_pdb.py
++++ b/Lib/test/test_pdb.py
+@@ -1580,6 +1580,7 @@ def test_pdb_next_command_subiterator():
+ (Pdb) continue
+ """
+
++@unittest.skipIf(True, 'Fails on Guix… but skipIf not taken into account?!')
+ def test_pdb_issue_20766():
+ """Test for reference leaks when the SIGINT handler is set.
+
+@@ -1598,11 +1599,11 @@ def test_pdb_issue_20766():
+ > <doctest test.test_pdb.test_pdb_issue_20766[0]>(6)test_function()
+ -> print('pdb %d: %s' % (i, sess._previous_sigint_handler))
+ (Pdb) continue
+- pdb 1: <built-in function default_int_handler>
++ pdb 1: 1
+ > <doctest test.test_pdb.test_pdb_issue_20766[0]>(6)test_function()
+ -> print('pdb %d: %s' % (i, sess._previous_sigint_handler))
+ (Pdb) continue
+- pdb 2: <built-in function default_int_handler>
++ pdb 2: 1
+ """
+
+ def test_pdb_issue_43318():
+diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py
+index 2ab6f6a986..8cf6b4d1c8 100644
+--- a/Lib/test/test_regrtest.py
++++ b/Lib/test/test_regrtest.py
+@@ -1049,6 +1049,7 @@ def test_fromfile(self):
+ output = self.run_tests('--fromfile', filename)
+ self.check_executed_tests(output, tests, stats=stats)
+
++ @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)
+@@ -1066,6 +1067,7 @@ def test_slowest(self):
+ % (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
+index 317e7ca8f8..7f272daf24 100644
+--- a/Lib/test/test_resource.py
++++ b/Lib/test/test_resource.py
+@@ -151,6 +151,7 @@ def test_freebsd_contants(self):
+
+ @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
+index bf60f37934..5e3a96380a 100644
+--- a/Lib/test/test_shutil.py
++++ b/Lib/test/test_shutil.py
+@@ -1743,6 +1743,7 @@ def test_make_archive(self):
+ base_name = os.path.join(tmpdir, 'archive')
+ self.assertRaises(ValueError, make_archive, base_name, 'xxx')
+
++ @unittest.skipIf(True, "The Guix build container has no root user")
+ @support.requires_zlib()
+ def test_make_archive_owner_group(self):
+ # testing make_archive with owner and group, with various combinations
+@@ -1771,6 +1772,7 @@ def test_make_archive_owner_group(self):
+ self.assertTrue(os.path.isfile(res))
+
+
++ @unittest.skipIf(True, "The Guix build container has no root user")
+ @support.requires_zlib()
+ @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support")
+ def test_tarfile_root_owner(self):
+diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py
+index 637a0ca3b3..2fb804e340 100644
+--- a/Lib/test/test_signal.py
++++ b/Lib/test/test_signal.py
+@@ -160,6 +160,7 @@ def test_valid_signals(self):
+ self.assertLess(signum, signal.NSIG)
+
+ @unittest.skipUnless(sys.executable, "sys.executable required.")
++ @unittest.skipUnless(sys.stdin.isatty(), "KeyboardInterrupts require a TTY device")
+ @support.requires_subprocess()
+ def test_keyboard_interrupt_exit_code(self):
+ """KeyboardInterrupt triggers exit via SIGINT."""
+@@ -211,6 +212,7 @@ def test_issue9324(self):
+ signal.signal(7, handler)
+
+ @unittest.skipUnless(sys.executable, "sys.executable required.")
++ @unittest.skipUnless(sys.stdin.isatty(), "KeyboardInterrupts require a TTY device")
+ @support.requires_subprocess()
+ def test_keyboard_interrupt_exit_code(self):
+ """KeyboardInterrupt triggers an exit using STATUS_CONTROL_C_EXIT."""
+@@ -1407,6 +1409,7 @@ def cycle_handlers():
+
+ 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)
+@@ -1452,6 +1455,7 @@ def __del__(self):
+
+ class PidfdSignalTest(unittest.TestCase):
+
++ @unittest.skipUnless(sys.stdin.isatty(), "KeyboardInterrupts require a TTY device")
+ @unittest.skipUnless(
+ hasattr(signal, "pidfd_send_signal"),
+ "pidfd support not built in",
+diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
+index 4eb5af99d6..9c7b8f6dbc 100644
+--- a/Lib/test/test_socket.py
++++ b/Lib/test/test_socket.py
+@@ -1016,6 +1016,8 @@ def testHostnameRes(self):
+ 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 [socket_helper.HOSTv4, '10.0.0.1', '255.255.255.255']:
+ self.assertEqual(socket.gethostbyname(addr), addr)
+@@ -1161,6 +1163,8 @@ def testNtoHErrors(self):
+ self.assertRaises(OverflowError, socket.ntohl, k)
+ self.assertRaises(OverflowError, socket.htonl, 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.
+@@ -1521,6 +1525,8 @@ def test_sio_loopback_fast_path(self):
+ 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)
+@@ -1653,6 +1659,8 @@ def test_getnameinfo(self):
+ # 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
+index 50766c2548..0c7eb7a83a 100644
+--- a/Lib/test/test_spwd.py
++++ b/Lib/test/test_spwd.py
+@@ -9,8 +9,7 @@
+ spwd = import_helper.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):
+@@ -60,8 +59,7 @@ def test_getspnam(self):
+ 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
+index 71489ea493..33351919fe 100644
+--- a/Lib/test/test_tarfile.py
++++ b/Lib/test/test_tarfile.py
+@@ -2911,9 +2911,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
+index 00d9e591c7..2515603715 100644
+--- a/Lib/test/test_threading.py
++++ b/Lib/test/test_threading.py
+@@ -1962,6 +1962,7 @@ def check_interrupt_main_noerror(self, signum):
+ # Restore original handler
+ signal.signal(signum, handler)
+
++ @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.
+@@ -1973,6 +1974,8 @@ def call_interrupt():
+ 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/Lib/test/test_tools/test_freeze.py b/Lib/test/test_tools/test_freeze.py
+index 0e7ed67de7..6539a2983b 100644
+--- a/Lib/test/test_tools/test_freeze.py
++++ b/Lib/test/test_tools/test_freeze.py
+@@ -23,6 +23,7 @@
+ 'test is too slow with PGO')
+ class TestFreeze(unittest.TestCase):
+
++ @unittest.skipIf(True, 'Fails on Guix.')
+ @support.requires_resource('cpu') # Building Python is slow
+ def test_freeze_simple_script(self):
+ script = textwrap.dedent("""
+diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py
+index 515c3840cb..a96dfad0fe 100644
+--- a/Lib/test/test_unicodedata.py
++++ b/Lib/test/test_unicodedata.py
+@@ -342,6 +342,7 @@ def test_linebreak_7643(self):
+ self.assertEqual(len(lines), 1,
+ r"\u%.4x should not be a linebreak" % i)
+
++@requires_resource('network')
+ class NormalizationTest(unittest.TestCase):
+ @staticmethod
+ def check_version(testfile):
+diff --git a/Tools/scripts/run_tests.py b/Tools/scripts/run_tests.py
+index 445a34ae3e..8f750537c3 100644
+--- a/Tools/scripts/run_tests.py
++++ b/Tools/scripts/run_tests.py
+@@ -69,7 +69,7 @@ def main(regrtest_args):
+ else:
+ 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'])
+
+ if cross_compile and hostrunner:
+ # If HOSTRUNNER is set and -p/--python option is not given, then
diff --git a/gnu/packages/python.scm b/gnu/packages/python.scm
index 51d5f598d7..25fe83ea69 100644
--- a/gnu/packages/python.scm
+++ b/gnu/packages/python.scm
@@ -55,7 +55,7 @@
;;; Copyright © 2018, 2019, 2020, 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;; Copyright © 2018 Luther Thompson <lutheroto@gmail.com>
;;; Copyright © 2018 Vagrant Cascadian <vagrant@debian.org>
-;;; Copyright © 2019 Tanguy Le Carrour <tanguy@bioneland.org>
+;;; Copyright © 2019, 2024 Tanguy Le Carrour <tanguy@bioneland.org>
;;; Copyright © 2020, 2023 Janneke Nieuwenhuizen <janneke@gnu.org>
;;; Copyright © 2020, 2021 Greg Hogan <code@greghogan.com>
;;; Copyright © 2022 Philip McGrath <philip@philipmcgrath.com>
@@ -596,6 +596,389 @@ (define-public python-3.10
(variable "PYTHONTZPATH")
(files (list "share/zoneinfo")))))))
+(define-public python-3.12
+ (package
+ (name "python-next")
+ (version "3.12.2")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (string-append "https://www.python.org/ftp/python/" version
+ "/Python-" version ".tar.xz"))
+ (sha256
+ (base32 "0w6qyfhc912xxav9x9pifwca40b4l49vy52wai9j0gc1mhni2a5y"))
+ (patches (search-patches "python-3-deterministic-build-info.patch"
+ "python-3.12-fix-tests.patch"
+ "python-3-hurd-configure.patch"))
+ (modules '((guix build utils)))
+ (snippet '(begin
+ ;; Delete the bundled copy of libexpat.
+ (delete-file-recursively "Modules/expat")
+ (substitute* "Modules/Setup"
+ ;; Link Expat instead of embedding the bundled one.
+ (("^#pyexpat.*")
+ "pyexpat pyexpat.c -lexpat\n"))
+ ;; Delete windows binaries
+ (for-each delete-file
+ (find-files "Lib/distutils/command" "\\.exe$"))))))
+ (outputs '("out" "tk" ;tkinter; adds 50 MiB to the closure
+ "idle")) ;programming environment; weighs 5MB
+ (build-system gnu-build-system)
+ (arguments
+ `(#:test-target "test"
+ #:configure-flags (list "--enable-shared" ;allow embedding
+ "--with-system-expat" ;for XML support
+ "--with-system-ffi" ;build ctypes
+ "--with-ensurepip=install" ;install pip and setuptools
+ "--with-computed-gotos" ;main interpreter loop optimization
+ "--enable-unicode=ucs4"
+ "--without-static-libpython"
+
+ ;; FIXME: These flags makes Python significantly faster, but
+ ;; leads to non-reproducible binaries.
+ ;; "--with-lto" ;increase size by 20MB, but 15% speedup
+ ;; "--enable-optimizations"
+
+ ;; Prevent the installed _sysconfigdata.py from retaining a reference
+ ;; to coreutils.
+ "INSTALL=install -c"
+ "MKDIR_P=mkdir -p"
+
+ ;; Disable runtime check failing if cross-compiling, see:
+ ;; https://lists.yoctoproject.org/pipermail/poky/2013-June/008997.html
+ ,@(if (%current-target-system)
+ '("ac_cv_buggy_getaddrinfo=no"
+ "ac_cv_file__dev_ptmx=no"
+ "ac_cv_file__dev_ptc=no")
+ '())
+ ;; -fno-semantic-interposition reinstates some optimizations by gcc
+ ;; leading to around 15% speedup. This is the default starting from
+ ;; python 3.10.
+ "CFLAGS=-fno-semantic-interposition"
+ (string-append "LDFLAGS=-Wl,-rpath="
+ (assoc-ref %outputs "out")
+ "/lib"
+ " -fno-semantic-interposition"))
+ ;; With no -j argument tests use all available cpus, so provide one.
+ #:make-flags (list (string-append (format #f "TESTOPTS=-j~d"
+ (parallel-job-count))
+ ;; those tests fail on low-memory systems
+ " --exclude test_mmap test_socket test_threading test_asyncio"
+ ,@(if (system-hurd?)
+ '(" test_posix" ;multiple errors
+ " test_time"
+ " test_pty"
+ " test_shutil"
+ " test_tempfile" ;chflags: invalid argument:
+ ;; tbv14c9t/dir0/dir0/dir0/test0.txt
+ " test_os" ;stty: 'standard input':
+ ;; Inappropriate ioctl for device
+ " test_openpty" ;No such file or directory
+ " test_selectors" ;assertEqual(NUM_FDS // 2, len(fds))
+ ;; 32752 != 4
+ " test_compileall" ;multiple errors
+ " test_poll" ;list index out of range
+ " test_subprocess" ;runs over 10min
+ " test_asyncore" ;multiple errors
+ " test_threadsignals"
+ " test_eintr" ;Process return code is -14
+ " test_io" ;multiple errors
+ " test_logging"
+ " test_signal"
+ " test_flags" ;ERROR
+ " test_bidirectional_pty"
+ " test_create_unix_connection"
+ " test_unix_sock_client_ops"
+ " test_open_unix_connection"
+ " test_open_unix_connection_error"
+ " test_read_pty_output"
+ " test_write_pty"
+ " test_concurrent_futures" ;freeze
+ " test_venv" ;freeze
+ " test_multiprocessing_forkserver" ;runs over 10min
+ " test_multiprocessing_spawn" ;runs over 10min
+ " test_builtin"
+ " test_capi"
+ " test_dbm_ndbm"
+ " test_exceptions"
+ " test_faulthandler"
+ " test_getopt"
+ " test_importlib"
+ " test_json"
+ " test_multiprocessing_fork"
+ " test_multiprocessing_main_handling"
+ " test_pdb "
+ " test_regrtest"
+ " test_sqlite")
+ '())))
+
+ #:modules ((ice-9 ftw)
+ (ice-9 match)
+ (guix build utils)
+ (guix build gnu-build-system))
+
+ #:phases (modify-phases %standard-phases
+ ,@(if (system-hurd?)
+ `((add-after 'unpack
+ 'disable-multi-processing
+ (lambda _
+ (substitute* "Makefile.pre.in"
+ (("-j0")
+ "-j1")))))
+ '())
+ (add-before 'configure 'patch-lib-shells
+ (lambda _
+ ;; This variable is used in setup.py to enable cross compilation
+ ;; specific switches. As it is not set properly by configure
+ ;; script, set it manually.
+ ,@(if (%current-target-system)
+ '((setenv "_PYTHON_HOST_PLATFORM" ""))
+ '())
+ ;; Filter for existing files, since some may not exist in all
+ ;; versions of python that are built with this recipe.
+ (substitute* (filter file-exists?
+ '("Lib/subprocess.py"
+ "Lib/popen2.py"
+ "Lib/distutils/tests/test_spawn.py"
+ "Lib/test/support/__init__.py"
+ "Lib/test/test_subprocess.py"))
+ (("/bin/sh")
+ (which "sh")))))
+ (add-before 'configure 'do-not-record-configure-flags
+ (lambda* (#:key configure-flags #:allow-other-keys)
+ ;; Remove configure flags from the installed '_sysconfigdata.py'
+ ;; and 'Makefile' so we don't end up keeping references to the
+ ;; build tools.
+ ;;
+ ;; Preserve at least '--with-system-ffi' since otherwise the
+ ;; thing tries to build libffi, fails, and we end up with a
+ ;; Python that lacks ctypes.
+ (substitute* "configure"
+ (("^CONFIG_ARGS=.*$")
+ (format #f "CONFIG_ARGS='~a'\n"
+ (if (member "--with-system-ffi"
+ configure-flags)
+ "--with-system-ffi" ""))))))
+ (add-before 'check 'pre-check
+ (lambda _
+ ;; 'Lib/test/test_site.py' needs a valid $HOME
+ (setenv "HOME"
+ (getcwd))))
+ (add-after 'unpack 'set-source-file-times-to-1980
+ ;; XXX One of the tests uses a ZIP library to pack up some of the
+ ;; source tree, and fails with "ZIP does not support timestamps
+ ;; before 1980". Work around this by setting the file times in the
+ ;; source tree to sometime in early 1980.
+ (lambda _
+ (let ((circa-1980 (* 10 366 24 60 60)))
+ (ftw "."
+ (lambda (file stat flag)
+ (utime file circa-1980 circa-1980) #t)))))
+ (add-after 'unpack 'remove-windows-binaries
+ (lambda _
+ ;; Delete .exe from embedded .whl (zip) files
+ (for-each (lambda (whl)
+ (let ((dir "whl-content")
+ (circa-1980 (* 10 366 24 60 60)))
+ (mkdir-p dir)
+ (with-directory-excursion dir
+ (let ((whl (string-append "../" whl)))
+ (invoke "unzip" whl)
+ (for-each delete-file
+ (find-files "." "\\.exe$"))
+ (delete-file whl)
+ ;; Reset timestamps to prevent them from ending
+ ;; up in the Zip archive.
+ (ftw "."
+ (lambda (file stat flag)
+ (utime file circa-1980
+ circa-1980) #t))
+ (apply invoke "zip" "-X" whl
+ (find-files "."
+ #:directories? #t))))
+ (delete-file-recursively dir)))
+ (find-files "Lib/ensurepip" "\\.whl$"))))
+ (add-after 'install 'remove-tests
+ ;; Remove 25 MiB of unneeded unit tests. Keep test_support.*
+ ;; because these files are used by some libraries out there.
+ (lambda* (#:key outputs #:allow-other-keys)
+ (let ((out (assoc-ref outputs "out")))
+ (match (scandir (string-append out "/lib")
+ (lambda (name)
+ (string-prefix? "python" name)))
+ ((pythonX.Y)
+ (let ((testdir (string-append out "/lib/" pythonX.Y
+ "/test")))
+ (with-directory-excursion testdir
+ (for-each delete-file-recursively
+ (scandir testdir
+ (match-lambda
+ ((or "." "..")
+ #f)
+ ("support" #f)
+ (file (not (string-prefix?
+ "test_support."
+ file))))))
+ (call-with-output-file "__init__.py"
+ (const #t))))
+ (let ((libdir (string-append out "/lib/" pythonX.Y)))
+ (for-each (lambda (directory)
+ (let ((dir (string-append libdir "/"
+ directory)))
+ (when (file-exists? dir)
+ (delete-file-recursively dir))))
+ '("email/test" "ctypes/test"
+ "unittest/test"
+ "tkinter/test"
+ "sqlite3/test"
+ "bsddb/test"
+ "lib-tk/test"
+ "json/tests"
+ "distutils/tests"))))))))
+ (add-after 'remove-tests 'move-tk-inter
+ (lambda* (#:key outputs inputs #:allow-other-keys)
+ ;; When Tkinter support is built move it to a separate output so
+ ;; that the main output doesn't contain a reference to Tcl/Tk.
+ (let ((out (assoc-ref outputs "out"))
+ (tk (assoc-ref outputs "tk")))
+ (when tk
+ (match (find-files out "tkinter.*\\.so")
+ ((tkinter.so)
+ ;; The .so is in OUT/lib/pythonX.Y/lib-dynload, but we
+ ;; want it under TK/lib/pythonX.Y/site-packages.
+ (let* ((len (string-length out))
+ (target (string-append tk "/"
+ (string-drop (dirname
+ (dirname
+ tkinter.so))
+ len)
+ "/site-packages")))
+ (install-file tkinter.so target)
+ (delete-file tkinter.so))))
+ ;; Remove explicit store path references.
+ (let ((tcl (assoc-ref inputs "tcl"))
+ (tk (assoc-ref inputs "tk")))
+ (substitute* (find-files (string-append out "/lib")
+ "^(_sysconfigdata_.*\\.py|Makefile)$")
+ (((string-append "-L" tk "/lib")) "")
+ (((string-append "-L" tcl "/lib")) "")))))))
+ (add-after 'move-tk-inter 'move-idle
+ (lambda* (#:key outputs #:allow-other-keys)
+ ;; when idle is built, move it to a separate output to save some
+ ;; space (5MB)
+ (let ((out (assoc-ref outputs "out"))
+ (idle (assoc-ref outputs "idle")))
+ (when idle
+ (for-each (lambda (file)
+ (let ((target (string-append idle
+ "/bin/"
+ (basename
+ file))))
+ (install-file file
+ (dirname target))
+ (delete-file file)))
+ (find-files (string-append out "/bin")
+ "^idle"))
+ (match (find-files out "^idlelib$"
+ #:directories? #t)
+ ((idlelib)
+ (let* ((len (string-length out))
+ (target (string-append idle "/"
+ (string-drop
+ idlelib len)
+ "/site-packages")))
+ (mkdir-p (dirname target))
+ (rename-file idlelib target))))))))
+ (add-after 'move-idle 'rebuild-bytecode
+ (lambda* (#:key outputs #:allow-other-keys)
+ (let ((out (assoc-ref outputs "out")))
+ ;; Disable hash randomization to ensure the generated .pycs
+ ;; are reproducible.
+ (setenv "PYTHONHASHSEED" "0")
+
+ (for-each (lambda (output)
+ ;; XXX: Delete existing pycs generated by the build
+ ;; system beforehand because the -f argument does
+ ;; not necessarily overwrite all files, leading to
+ ;; indeterministic results.
+ (for-each (lambda (pyc)
+ (delete-file pyc))
+ (find-files output "\\.pyc$"))
+
+ (apply invoke
+ `(,,(if (%current-target-system)
+ "python3"
+ '(string-append out
+ "/bin/python3")) "-m"
+ "compileall"
+ "-o"
+ "0"
+ "-o"
+ "1"
+ "-o"
+ "2"
+ "-f" ;force rebuild
+ "--invalidation-mode=unchecked-hash"
+ ;; Don't build lib2to3, because it's
+ ;; Python 2 code.
+ "-x"
+ "lib2to3/.*"
+ ,output)))
+ (map cdr outputs)))))
+ (add-before 'check 'set-TZDIR
+ (lambda* (#:key inputs native-inputs #:allow-other-keys)
+ ;; test_email requires the Olson time zone database.
+ (setenv "TZDIR"
+ (string-append (assoc-ref (or native-inputs
+ inputs) "tzdata")
+ "/share/zoneinfo"))))
+ (add-after 'install 'install-sitecustomize.py
+ ,(customize-site version)))))
+ (inputs (list bzip2
+ expat
+ gdbm
+ libffi ;for ctypes
+ sqlite ;for sqlite extension
+ openssl
+ readline
+ zlib
+ tcl
+ tk)) ;for tkinter
+ (native-inputs `(("tzdata" ,tzdata-for-tests)
+ ("unzip" ,unzip)
+ ("zip" ,(@ (gnu packages compression) zip))
+ ("pkg-config" ,pkg-config)
+ ("sitecustomize.py" ,(local-file (search-auxiliary-file
+ "python/sitecustomize.py")))
+ ;; When cross-compiling, a native version of Python itself is needed.
+ ,@(if (%current-target-system)
+ `(("python" ,this-package)
+ ("which" ,which))
+ '())))
+ (native-search-paths
+ (list (guix-pythonpath-search-path version)
+ ;; Used to locate tzdata by the zoneinfo module introduced in
+ ;; Python 3.9.
+ (search-path-specification
+ (variable "PYTHONTZPATH")
+ (files (list "share/zoneinfo")))))
+ (home-page "https://www.python.org")
+ (synopsis "High-level, dynamically-typed programming language")
+ (description
+ "Python is a remarkably powerful dynamic programming language that
+is used in a wide variety of application domains. Some of its key
+distinguishing features include: clear, readable syntax; strong
+introspection capabilities; intuitive object orientation; natural
+expression of procedural code; full modularity, supporting hierarchical
+packages; exception-based error handling; and very high level dynamic
+data types.")
+ (properties '((cpe-name . "python")))
+ (license license:psfl)))
+
+
+;; Next 3.x version.
+(define-public python-next python-3.12)
+
;; Current 3.x version.
(define-public python-3 python-3.10)
base-commit: a3a7d51a31957f185e4e6e3059610769d48ffd70
--
2.41.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [bug#60240] [PATCH v5] gnu: Add python-3.12 and python-next.
2022-12-21 15:32 [bug#60240] [PATCH] [WIP] gnu: Add python-3.11 Tanguy Le Carrour
` (5 preceding siblings ...)
2024-03-07 18:45 ` [bug#60240] [PATCH v4] " Tanguy Le Carrour
@ 2024-03-07 18:58 ` Tanguy Le Carrour
2024-11-08 8:00 ` bug#60240: " Lars-Dominik Braun
6 siblings, 1 reply; 18+ messages in thread
From: Tanguy Le Carrour @ 2024-03-07 18:58 UTC (permalink / raw)
To: 60240
Cc: Tanguy Le Carrour, Lars-Dominik Braun, Lars-Dominik Braun,
Marius Bakke, Munyoki Kilyungi, Sharlatan Hellseher, jgart
Patch v5 **actually** contains **all** the modifications announced
in v4. Sooooorry!
* gnu/packages/python.scm (python-3.12, python-next): New variables.
* gnu/packages/patches/python-3.12-fix-tests.patch: New file.
Change-Id: Ie393b732a8863569578e72e62603b75a1655a34e
Signed-off-by: Tanguy Le Carrour <tanguy@bioneland.org>
---
.../patches/python-3.12-fix-tests.patch | 334 +++++++++++++++
gnu/packages/python.scm | 387 +++++++++++++++++-
2 files changed, 720 insertions(+), 1 deletion(-)
create mode 100644 gnu/packages/patches/python-3.12-fix-tests.patch
diff --git a/gnu/packages/patches/python-3.12-fix-tests.patch b/gnu/packages/patches/python-3.12-fix-tests.patch
new file mode 100644
index 0000000000..fa5c8027ce
--- /dev/null
+++ b/gnu/packages/patches/python-3.12-fix-tests.patch
@@ -0,0 +1,334 @@
+From f0698133e7d6c353a3e6ae0fc62e57ba558a9bc0 Mon Sep 17 00:00:00 2001
+From: Maxim Cournoyer <maxim.cournoyer@gmail.com>
+Date: Wed, 28 Oct 2020 22:55:05 -0400
+Subject: [PATCH] Skip problematic Python 3 tests in Guix.
+
+A subset of the hunks in this patch is tracked upstream at
+https://bugs.python.org/issue38845, which was contributed by Tanguy Le
+Carrour <tanguy@bioneland.org>.
+
+diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py
+index e42c7ab4bd..8087c84dab 100644
+--- a/Lib/test/_test_multiprocessing.py
++++ b/Lib/test/_test_multiprocessing.py
+@@ -1695,6 +1695,7 @@ def _test_wait_result(cls, c, pid):
+ 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()
+@@ -4150,6 +4151,7 @@ def test_shared_memory_across_processes(self):
+ 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_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py
+index 85c8152d49..e35cfffe84 100644
+--- a/Lib/test/test_asyncio/test_base_events.py
++++ b/Lib/test/test_asyncio/test_base_events.py
+@@ -1377,6 +1377,8 @@ def test_create_connection_no_inet_pton(self, m_socket):
+ 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_ctypes/test_find.py b/Lib/test/test_ctypes/test_find.py
+index a41e94971d..1291af3057 100644
+--- a/Lib/test/test_ctypes/test_find.py
++++ b/Lib/test/test_ctypes/test_find.py
+@@ -117,6 +117,7 @@ def test_find_library_with_gcc(self):
+ with unittest.mock.patch("ctypes.util._findSoname_ldconfig", lambda *args: None):
+ self.assertNotEqual(find_library('c'), None)
+
++ @unittest.skipIf(True, 'Fails 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):
+diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py
+index 1ee9958445..ab6b41befe 100644
+--- a/Lib/test/test_generators.py
++++ b/Lib/test/test_generators.py
+@@ -34,6 +34,7 @@ def generator2(self):
+ 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
+index ec105ae1a0..ae4c5b672e 100644
+--- a/Lib/test/test_pathlib.py
++++ b/Lib/test/test_pathlib.py
+@@ -3069,6 +3069,7 @@ def test_rglob(self):
+ 'pwd module does not expose getpwall()')
+ @unittest.skipIf(sys.platform == "vxworks",
+ "no home directory on VxWorks")
++ @unittest.skipIf(True, "Guix builder home is '/' which causes trouble for these tests")
+ def test_expanduser(self):
+ P = self.cls
+ import_helper.import_module('pwd')
+diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
+index 51b844262e..004d3133cf 100644
+--- a/Lib/test/test_pdb.py
++++ b/Lib/test/test_pdb.py
+@@ -1580,6 +1580,7 @@ def test_pdb_next_command_subiterator():
+ (Pdb) continue
+ """
+
++@unittest.skipIf(True, 'Fails on Guix… but skipIf not taken into account?!')
+ def test_pdb_issue_20766():
+ """Test for reference leaks when the SIGINT handler is set.
+
+@@ -1598,11 +1599,11 @@ def test_pdb_issue_20766():
+ > <doctest test.test_pdb.test_pdb_issue_20766[0]>(6)test_function()
+ -> print('pdb %d: %s' % (i, sess._previous_sigint_handler))
+ (Pdb) continue
+- pdb 1: <built-in function default_int_handler>
++ pdb 1: 1
+ > <doctest test.test_pdb.test_pdb_issue_20766[0]>(6)test_function()
+ -> print('pdb %d: %s' % (i, sess._previous_sigint_handler))
+ (Pdb) continue
+- pdb 2: <built-in function default_int_handler>
++ pdb 2: 1
+ """
+
+ def test_pdb_issue_43318():
+diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py
+index 2ab6f6a986..8cf6b4d1c8 100644
+--- a/Lib/test/test_regrtest.py
++++ b/Lib/test/test_regrtest.py
+@@ -1049,6 +1049,7 @@ def test_fromfile(self):
+ output = self.run_tests('--fromfile', filename)
+ self.check_executed_tests(output, tests, stats=stats)
+
++ @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)
+@@ -1066,6 +1067,7 @@ def test_slowest(self):
+ % (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
+index 317e7ca8f8..7f272daf24 100644
+--- a/Lib/test/test_resource.py
++++ b/Lib/test/test_resource.py
+@@ -151,6 +151,7 @@ def test_freebsd_contants(self):
+
+ @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
+index bf60f37934..5e3a96380a 100644
+--- a/Lib/test/test_shutil.py
++++ b/Lib/test/test_shutil.py
+@@ -1743,6 +1743,7 @@ def test_make_archive(self):
+ base_name = os.path.join(tmpdir, 'archive')
+ self.assertRaises(ValueError, make_archive, base_name, 'xxx')
+
++ @unittest.skipIf(True, "The Guix build container has no root user")
+ @support.requires_zlib()
+ def test_make_archive_owner_group(self):
+ # testing make_archive with owner and group, with various combinations
+@@ -1771,6 +1772,7 @@ def test_make_archive_owner_group(self):
+ self.assertTrue(os.path.isfile(res))
+
+
++ @unittest.skipIf(True, "The Guix build container has no root user")
+ @support.requires_zlib()
+ @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support")
+ def test_tarfile_root_owner(self):
+diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py
+index 637a0ca3b3..2fb804e340 100644
+--- a/Lib/test/test_signal.py
++++ b/Lib/test/test_signal.py
+@@ -160,6 +160,7 @@ def test_valid_signals(self):
+ self.assertLess(signum, signal.NSIG)
+
+ @unittest.skipUnless(sys.executable, "sys.executable required.")
++ @unittest.skipUnless(sys.stdin.isatty(), "KeyboardInterrupts require a TTY device")
+ @support.requires_subprocess()
+ def test_keyboard_interrupt_exit_code(self):
+ """KeyboardInterrupt triggers exit via SIGINT."""
+@@ -211,6 +212,7 @@ def test_issue9324(self):
+ signal.signal(7, handler)
+
+ @unittest.skipUnless(sys.executable, "sys.executable required.")
++ @unittest.skipUnless(sys.stdin.isatty(), "KeyboardInterrupts require a TTY device")
+ @support.requires_subprocess()
+ def test_keyboard_interrupt_exit_code(self):
+ """KeyboardInterrupt triggers an exit using STATUS_CONTROL_C_EXIT."""
+@@ -1407,6 +1409,7 @@ def cycle_handlers():
+
+ 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)
+@@ -1452,6 +1455,7 @@ def __del__(self):
+
+ class PidfdSignalTest(unittest.TestCase):
+
++ @unittest.skipUnless(sys.stdin.isatty(), "KeyboardInterrupts require a TTY device")
+ @unittest.skipUnless(
+ hasattr(signal, "pidfd_send_signal"),
+ "pidfd support not built in",
+diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
+index 4eb5af99d6..9c7b8f6dbc 100644
+--- a/Lib/test/test_socket.py
++++ b/Lib/test/test_socket.py
+@@ -1016,6 +1016,8 @@ def testHostnameRes(self):
+ 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 [socket_helper.HOSTv4, '10.0.0.1', '255.255.255.255']:
+ self.assertEqual(socket.gethostbyname(addr), addr)
+@@ -1161,6 +1163,8 @@ def testNtoHErrors(self):
+ self.assertRaises(OverflowError, socket.ntohl, k)
+ self.assertRaises(OverflowError, socket.htonl, 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.
+@@ -1521,6 +1525,8 @@ def test_sio_loopback_fast_path(self):
+ 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)
+@@ -1653,6 +1659,8 @@ def test_getnameinfo(self):
+ # 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
+index 50766c2548..0c7eb7a83a 100644
+--- a/Lib/test/test_spwd.py
++++ b/Lib/test/test_spwd.py
+@@ -9,8 +9,7 @@
+ spwd = import_helper.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):
+@@ -60,8 +59,7 @@ def test_getspnam(self):
+ 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
+index 71489ea493..33351919fe 100644
+--- a/Lib/test/test_tarfile.py
++++ b/Lib/test/test_tarfile.py
+@@ -2911,9 +2911,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
+index 00d9e591c7..2515603715 100644
+--- a/Lib/test/test_threading.py
++++ b/Lib/test/test_threading.py
+@@ -1962,6 +1962,7 @@ def check_interrupt_main_noerror(self, signum):
+ # Restore original handler
+ signal.signal(signum, handler)
+
++ @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.
+@@ -1973,6 +1974,8 @@ def call_interrupt():
+ 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/Lib/test/test_tools/test_freeze.py b/Lib/test/test_tools/test_freeze.py
+index 0e7ed67de7..6539a2983b 100644
+--- a/Lib/test/test_tools/test_freeze.py
++++ b/Lib/test/test_tools/test_freeze.py
+@@ -23,6 +23,7 @@
+ 'test is too slow with PGO')
+ class TestFreeze(unittest.TestCase):
+
++ @unittest.skipIf(True, 'Fails on Guix.')
+ @support.requires_resource('cpu') # Building Python is slow
+ def test_freeze_simple_script(self):
+ script = textwrap.dedent("""
+diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py
+index 515c3840cb..a96dfad0fe 100644
+--- a/Lib/test/test_unicodedata.py
++++ b/Lib/test/test_unicodedata.py
+@@ -342,6 +342,7 @@ def test_linebreak_7643(self):
+ self.assertEqual(len(lines), 1,
+ r"\u%.4x should not be a linebreak" % i)
+
++@requires_resource('network')
+ class NormalizationTest(unittest.TestCase):
+ @staticmethod
+ def check_version(testfile):
+diff --git a/Tools/scripts/run_tests.py b/Tools/scripts/run_tests.py
+index 445a34ae3e..8f750537c3 100644
+--- a/Tools/scripts/run_tests.py
++++ b/Tools/scripts/run_tests.py
+@@ -69,7 +69,7 @@ def main(regrtest_args):
+ else:
+ 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'])
+
+ if cross_compile and hostrunner:
+ # If HOSTRUNNER is set and -p/--python option is not given, then
diff --git a/gnu/packages/python.scm b/gnu/packages/python.scm
index 51d5f598d7..df3ea7ca9a 100644
--- a/gnu/packages/python.scm
+++ b/gnu/packages/python.scm
@@ -55,7 +55,7 @@
;;; Copyright © 2018, 2019, 2020, 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;; Copyright © 2018 Luther Thompson <lutheroto@gmail.com>
;;; Copyright © 2018 Vagrant Cascadian <vagrant@debian.org>
-;;; Copyright © 2019 Tanguy Le Carrour <tanguy@bioneland.org>
+;;; Copyright © 2019, 2024 Tanguy Le Carrour <tanguy@bioneland.org>
;;; Copyright © 2020, 2023 Janneke Nieuwenhuizen <janneke@gnu.org>
;;; Copyright © 2020, 2021 Greg Hogan <code@greghogan.com>
;;; Copyright © 2022 Philip McGrath <philip@philipmcgrath.com>
@@ -596,6 +596,391 @@ (define-public python-3.10
(variable "PYTHONTZPATH")
(files (list "share/zoneinfo")))))))
+(define-public python-3.12
+ (package
+ (name "python-next")
+ (version "3.12.2")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (string-append "https://www.python.org/ftp/python/" version
+ "/Python-" version ".tar.xz"))
+ (sha256
+ (base32 "0w6qyfhc912xxav9x9pifwca40b4l49vy52wai9j0gc1mhni2a5y"))
+ (patches (search-patches "python-3-deterministic-build-info.patch"
+ "python-3.12-fix-tests.patch"
+ "python-3-hurd-configure.patch"))
+ (modules '((guix build utils)))
+ (snippet '(begin
+ ;; Delete the bundled copy of libexpat.
+ (delete-file-recursively "Modules/expat")
+ (substitute* "Modules/Setup"
+ ;; Link Expat instead of embedding the bundled one.
+ (("^#pyexpat.*")
+ "pyexpat pyexpat.c -lexpat\n"))
+ ;; Delete windows binaries
+ (for-each delete-file
+ (find-files "Lib/distutils/command" "\\.exe$"))))))
+ (outputs '("out" "tk" ;tkinter; adds 50 MiB to the closure
+ "idle")) ;programming environment; weighs 5MB
+ (build-system gnu-build-system)
+ (arguments
+ `(#:test-target "test"
+ #:configure-flags (list "--enable-shared" ;allow embedding
+ "--with-system-expat" ;for XML support
+ "--with-system-ffi" ;build ctypes
+ "--with-ensurepip=install" ;install pip and setuptools
+ "--with-computed-gotos" ;main interpreter loop optimization
+ "--enable-unicode=ucs4"
+ "--without-static-libpython"
+
+ ;; FIXME: These flags makes Python significantly faster,
+ ;; but leads to non-reproducible binaries.
+ ;; "--with-lto" ;increase size by 20MB, but 15% speedup
+ ;; "--enable-optimizations"
+
+ ;; Prevent the installed _sysconfigdata.py from retaining
+ ;; a reference to coreutils.
+ "INSTALL=install -c"
+ "MKDIR_P=mkdir -p"
+
+ ;; Disable runtime check failing if cross-compiling, see:
+ ;; https://lists.yoctoproject.org/pipermail/poky/2013-June/008997.html
+ ,@(if (%current-target-system)
+ '("ac_cv_buggy_getaddrinfo=no"
+ "ac_cv_file__dev_ptmx=no"
+ "ac_cv_file__dev_ptc=no")
+ '())
+ ;; -fno-semantic-interposition reinstates some
+ ;; optimizations by gcc leading to around 15% speedup.
+ ;; This is the default starting from python 3.10.
+ "CFLAGS=-fno-semantic-interposition"
+ (string-append "LDFLAGS=-Wl,-rpath="
+ (assoc-ref %outputs "out")
+ "/lib"
+ " -fno-semantic-interposition"))
+ ;; With no -j argument tests use all available cpus, so provide one.
+ #:make-flags (list (string-append (format #f "TESTOPTS=-j~d"
+ (parallel-job-count))
+ ;; those tests fail on low-memory systems
+ " --exclude test_mmap test_socket test_threading test_asyncio"
+ ,@(if (system-hurd?)
+ '(" test_posix" ;multiple errors
+ " test_time"
+ " test_pty"
+ " test_shutil"
+ " test_tempfile" ;chflags: invalid argument:
+ ;; tbv14c9t/dir0/dir0/dir0/test0.txt
+ " test_os" ;stty: 'standard input':
+ ;; Inappropriate ioctl for device
+ " test_openpty" ;No such file or directory
+ " test_selectors" ;assertEqual(NUM_FDS // 2, len(fds))
+ ;; 32752 != 4
+ " test_compileall" ;multiple errors
+ " test_poll" ;list index out of range
+ " test_subprocess" ;runs over 10min
+ " test_asyncore" ;multiple errors
+ " test_threadsignals"
+ " test_eintr" ;Process return code is -14
+ " test_io" ;multiple errors
+ " test_logging"
+ " test_signal"
+ " test_flags" ;ERROR
+ " test_bidirectional_pty"
+ " test_create_unix_connection"
+ " test_unix_sock_client_ops"
+ " test_open_unix_connection"
+ " test_open_unix_connection_error"
+ " test_read_pty_output"
+ " test_write_pty"
+ " test_concurrent_futures" ;freeze
+ " test_venv" ;freeze
+ " test_multiprocessing_forkserver" ;runs over 10min
+ " test_multiprocessing_spawn" ;runs over 10min
+ " test_builtin"
+ " test_capi"
+ " test_dbm_ndbm"
+ " test_exceptions"
+ " test_faulthandler"
+ " test_getopt"
+ " test_importlib"
+ " test_json"
+ " test_multiprocessing_fork"
+ " test_multiprocessing_main_handling"
+ " test_pdb "
+ " test_regrtest"
+ " test_sqlite")
+ '())))
+
+ #:modules ((ice-9 ftw)
+ (ice-9 match)
+ (guix build utils)
+ (guix build gnu-build-system))
+
+ #:phases (modify-phases %standard-phases
+ ,@(if (system-hurd?)
+ `((add-after 'unpack
+ 'disable-multi-processing
+ (lambda _
+ (substitute* "Makefile.pre.in"
+ (("-j0")
+ "-j1")))))
+ '())
+ (add-before 'configure 'patch-lib-shells
+ (lambda _
+ ;; This variable is used in setup.py to enable cross compilation
+ ;; specific switches. As it is not set properly by configure
+ ;; script, set it manually.
+ ,@(if (%current-target-system)
+ '((setenv "_PYTHON_HOST_PLATFORM" ""))
+ '())
+ ;; Filter for existing files, since some may not exist in all
+ ;; versions of python that are built with this recipe.
+ (substitute* (filter file-exists?
+ '("Lib/subprocess.py"
+ "Lib/popen2.py"
+ "Lib/distutils/tests/test_spawn.py"
+ "Lib/test/support/__init__.py"
+ "Lib/test/test_subprocess.py"))
+ (("/bin/sh")
+ (which "sh")))))
+ (add-before 'configure 'do-not-record-configure-flags
+ (lambda* (#:key configure-flags #:allow-other-keys)
+ ;; Remove configure flags from the installed '_sysconfigdata.py'
+ ;; and 'Makefile' so we don't end up keeping references to the
+ ;; build tools.
+ ;;
+ ;; Preserve at least '--with-system-ffi' since otherwise the
+ ;; thing tries to build libffi, fails, and we end up with a
+ ;; Python that lacks ctypes.
+ (substitute* "configure"
+ (("^CONFIG_ARGS=.*$")
+ (format #f "CONFIG_ARGS='~a'\n"
+ (if (member "--with-system-ffi"
+ configure-flags)
+ "--with-system-ffi" ""))))))
+ (add-before 'check 'pre-check
+ (lambda _
+ ;; 'Lib/test/test_site.py' needs a valid $HOME
+ (setenv "HOME"
+ (getcwd))))
+ (add-after 'unpack 'set-source-file-times-to-1980
+ ;; XXX One of the tests uses a ZIP library to pack up some of the
+ ;; source tree, and fails with "ZIP does not support timestamps
+ ;; before 1980". Work around this by setting the file times in the
+ ;; source tree to sometime in early 1980.
+ (lambda _
+ (let ((circa-1980 (* 10 366 24 60 60)))
+ (ftw "."
+ (lambda (file stat flag)
+ (utime file circa-1980 circa-1980) #t)))))
+ (add-after 'unpack 'remove-windows-binaries
+ (lambda _
+ ;; Delete .exe from embedded .whl (zip) files
+ (for-each (lambda (whl)
+ (let ((dir "whl-content")
+ (circa-1980 (* 10 366 24 60 60)))
+ (mkdir-p dir)
+ (with-directory-excursion dir
+ (let ((whl (string-append "../" whl)))
+ (invoke "unzip" whl)
+ (for-each delete-file
+ (find-files "." "\\.exe$"))
+ (delete-file whl)
+ ;; Reset timestamps to prevent them from ending
+ ;; up in the Zip archive.
+ (ftw "."
+ (lambda (file stat flag)
+ (utime file circa-1980
+ circa-1980) #t))
+ (apply invoke "zip" "-X" whl
+ (find-files "."
+ #:directories? #t))))
+ (delete-file-recursively dir)))
+ (find-files "Lib/ensurepip" "\\.whl$"))))
+ (add-after 'install 'remove-tests
+ ;; Remove 25 MiB of unneeded unit tests. Keep test_support.*
+ ;; because these files are used by some libraries out there.
+ (lambda* (#:key outputs #:allow-other-keys)
+ (let ((out (assoc-ref outputs "out")))
+ (match (scandir (string-append out "/lib")
+ (lambda (name)
+ (string-prefix? "python" name)))
+ ((pythonX.Y)
+ (let ((testdir (string-append out "/lib/" pythonX.Y
+ "/test")))
+ (with-directory-excursion testdir
+ (for-each delete-file-recursively
+ (scandir testdir
+ (match-lambda
+ ((or "." "..")
+ #f)
+ ("support" #f)
+ (file (not (string-prefix?
+ "test_support."
+ file))))))
+ (call-with-output-file "__init__.py"
+ (const #t))))
+ (let ((libdir (string-append out "/lib/" pythonX.Y)))
+ (for-each (lambda (directory)
+ (let ((dir (string-append libdir "/"
+ directory)))
+ (when (file-exists? dir)
+ (delete-file-recursively dir))))
+ '("email/test" "ctypes/test"
+ "unittest/test"
+ "tkinter/test"
+ "sqlite3/test"
+ "bsddb/test"
+ "lib-tk/test"
+ "json/tests"
+ "distutils/tests"))))))))
+ (add-after 'remove-tests 'move-tk-inter
+ (lambda* (#:key outputs inputs #:allow-other-keys)
+ ;; When Tkinter support is built move it to a separate output so
+ ;; that the main output doesn't contain a reference to Tcl/Tk.
+ (let ((out (assoc-ref outputs "out"))
+ (tk (assoc-ref outputs "tk")))
+ (when tk
+ (match (find-files out "tkinter.*\\.so")
+ ((tkinter.so)
+ ;; The .so is in OUT/lib/pythonX.Y/lib-dynload, but we
+ ;; want it under TK/lib/pythonX.Y/site-packages.
+ (let* ((len (string-length out))
+ (target (string-append tk "/"
+ (string-drop (dirname
+ (dirname
+ tkinter.so))
+ len)
+ "/site-packages")))
+ (install-file tkinter.so target)
+ (delete-file tkinter.so))))
+ ;; Remove explicit store path references.
+ (let ((tcl (assoc-ref inputs "tcl"))
+ (tk (assoc-ref inputs "tk")))
+ (substitute* (find-files (string-append out "/lib")
+ "^(_sysconfigdata_.*\\.py|Makefile)$")
+ (((string-append "-L" tk "/lib"))
+ "")
+ (((string-append "-L" tcl "/lib"))
+ "")))))))
+ (add-after 'move-tk-inter 'move-idle
+ (lambda* (#:key outputs #:allow-other-keys)
+ ;; when idle is built, move it to a separate output to save some
+ ;; space (5MB)
+ (let ((out (assoc-ref outputs "out"))
+ (idle (assoc-ref outputs "idle")))
+ (when idle
+ (for-each (lambda (file)
+ (let ((target (string-append idle
+ "/bin/"
+ (basename
+ file))))
+ (install-file file
+ (dirname target))
+ (delete-file file)))
+ (find-files (string-append out "/bin")
+ "^idle"))
+ (match (find-files out "^idlelib$"
+ #:directories? #t)
+ ((idlelib)
+ (let* ((len (string-length out))
+ (target (string-append idle "/"
+ (string-drop
+ idlelib len)
+ "/site-packages")))
+ (mkdir-p (dirname target))
+ (rename-file idlelib target))))))))
+ (add-after 'move-idle 'rebuild-bytecode
+ (lambda* (#:key outputs #:allow-other-keys)
+ (let ((out (assoc-ref outputs "out")))
+ ;; Disable hash randomization to ensure the generated .pycs
+ ;; are reproducible.
+ (setenv "PYTHONHASHSEED" "0")
+
+ (for-each (lambda (output)
+ ;; XXX: Delete existing pycs generated by the build
+ ;; system beforehand because the -f argument does
+ ;; not necessarily overwrite all files, leading to
+ ;; indeterministic results.
+ (for-each (lambda (pyc)
+ (delete-file pyc))
+ (find-files output "\\.pyc$"))
+
+ (apply invoke
+ `(,,(if (%current-target-system)
+ "python3"
+ '(string-append out
+ "/bin/python3")) "-m"
+ "compileall"
+ "-o"
+ "0"
+ "-o"
+ "1"
+ "-o"
+ "2"
+ "-f" ;force rebuild
+ "--invalidation-mode=unchecked-hash"
+ ;; Don't build lib2to3, because it's
+ ;; Python 2 code.
+ "-x"
+ "lib2to3/.*"
+ ,output)))
+ (map cdr outputs)))))
+ (add-before 'check 'set-TZDIR
+ (lambda* (#:key inputs native-inputs #:allow-other-keys)
+ ;; test_email requires the Olson time zone database.
+ (setenv "TZDIR"
+ (string-append (assoc-ref (or native-inputs
+ inputs) "tzdata")
+ "/share/zoneinfo"))))
+ (add-after 'install 'install-sitecustomize.py
+ ,(customize-site version)))))
+ (inputs (list bzip2
+ expat
+ gdbm
+ libffi ;for ctypes
+ sqlite ;for sqlite extension
+ openssl
+ readline
+ zlib
+ tcl
+ tk)) ;for tkinter
+ (native-inputs `(("tzdata" ,tzdata-for-tests)
+ ("unzip" ,unzip)
+ ("zip" ,(@ (gnu packages compression) zip))
+ ("pkg-config" ,pkg-config)
+ ("sitecustomize.py" ,(local-file (search-auxiliary-file
+ "python/sitecustomize.py")))
+ ;; When cross-compiling, a native version of Python itself is needed.
+ ,@(if (%current-target-system)
+ `(("python" ,this-package)
+ ("which" ,which))
+ '())))
+ (native-search-paths
+ (list (guix-pythonpath-search-path version)
+ ;; Used to locate tzdata by the zoneinfo module introduced in
+ ;; Python 3.9.
+ (search-path-specification
+ (variable "PYTHONTZPATH")
+ (files (list "share/zoneinfo")))))
+ (home-page "https://www.python.org")
+ (synopsis "High-level, dynamically-typed programming language")
+ (description
+ "Python is a remarkably powerful dynamic programming language that
+is used in a wide variety of application domains. Some of its key
+distinguishing features include: clear, readable syntax; strong
+introspection capabilities; intuitive object orientation; natural
+expression of procedural code; full modularity, supporting hierarchical
+packages; exception-based error handling; and very high level dynamic
+data types.")
+ (properties '((cpe-name . "python")))
+ (license license:psfl)))
+
+
+;; Next 3.x version.
+(define-public python-next python-3.12)
+
;; Current 3.x version.
(define-public python-3 python-3.10)
base-commit: a3a7d51a31957f185e4e6e3059610769d48ffd70
--
2.41.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* bug#60240: [PATCH v5] gnu: Add python-3.12 and python-next.
2024-03-07 18:58 ` [bug#60240] [PATCH v5] " Tanguy Le Carrour
@ 2024-11-08 8:00 ` Lars-Dominik Braun
2024-11-08 10:08 ` [bug#60240] " Tanguy LE CARROUR
0 siblings, 1 reply; 18+ messages in thread
From: Lars-Dominik Braun @ 2024-11-08 8:00 UTC (permalink / raw)
To: Tanguy Le Carrour; +Cc: 60240-done
Hi,
> Patch v5 **actually** contains **all** the modifications announced
> in v4. Sooooorry!
it looks like I merged this patch, but I did not close this issue,
so closing.
Lars
^ permalink raw reply [flat|nested] 18+ messages in thread
* [bug#60240] [PATCH v5] gnu: Add python-3.12 and python-next.
2024-11-08 8:00 ` bug#60240: " Lars-Dominik Braun
@ 2024-11-08 10:08 ` Tanguy LE CARROUR
0 siblings, 0 replies; 18+ messages in thread
From: Tanguy LE CARROUR @ 2024-11-08 10:08 UTC (permalink / raw)
To: Lars-Dominik Braun; +Cc: 60240-done
Hi Lars,
Quoting Lars-Dominik Braun (2024-11-08 09:00:09)
> > Patch v5 **actually** contains **all** the modifications announced
> > in v4. Sooooorry!
>
> it looks like I merged this patch, but I did not close this issue,
> so closing.
Thanks!
--
Tanguy
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2024-11-08 10:16 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-12-21 15:32 [bug#60240] [PATCH] [WIP] gnu: Add python-3.11 Tanguy Le Carrour
2023-01-06 17:36 ` Simon Tournier
2023-01-09 15:59 ` Tanguy LE CARROUR
2023-03-12 23:35 ` [bug#60240] Python 3.10 in core-updates Andreas Enge
2024-02-19 21:27 ` John Kehayias via Guix-patches via
2024-02-20 14:18 ` Tanguy LE CARROUR
2024-02-21 12:13 ` [bug#60240] [PATCH v2] gnu: Add python-3.12 and python-next Tanguy Le Carrour
2024-02-21 18:36 ` Tanguy Le Carrour
2024-02-22 9:07 ` Tanguy LE CARROUR
2024-02-25 14:08 ` Lars-Dominik Braun
2024-02-26 8:25 ` Tanguy LE CARROUR
2024-03-02 9:59 ` Lars-Dominik Braun
2024-03-06 12:49 ` Tanguy LE CARROUR
2024-03-06 12:55 ` [bug#60240] [PATCH v3] " Tanguy Le Carrour
2024-03-07 18:45 ` [bug#60240] [PATCH v4] " Tanguy Le Carrour
2024-03-07 18:58 ` [bug#60240] [PATCH v5] " Tanguy Le Carrour
2024-11-08 8:00 ` bug#60240: " Lars-Dominik Braun
2024-11-08 10:08 ` [bug#60240] " Tanguy LE CARROUR
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/guix.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).