diff options
Diffstat (limited to 'meta/recipes-devtools/python/python3')
55 files changed, 2651 insertions, 2451 deletions
diff --git a/meta/recipes-devtools/python/python3/0001-Avoid-shebang-overflow-on-python-config.py.patch b/meta/recipes-devtools/python/python3/0001-Avoid-shebang-overflow-on-python-config.py.patch new file mode 100644 index 0000000000..0d807db39f --- /dev/null +++ b/meta/recipes-devtools/python/python3/0001-Avoid-shebang-overflow-on-python-config.py.patch @@ -0,0 +1,30 @@ +From 365399f17d35719d828ddd49182dcb401fb7791c Mon Sep 17 00:00:00 2001 +From: Paulo Neves <ptsneves@gmail.com> +Date: Tue, 7 Jun 2022 16:16:41 +0200 +Subject: [PATCH] Avoid shebang overflow on python-config.py + +The whole native path may be too big, leading to shebang +overflow. Let's just use the env shebang. + +Denial reason: [1] + +Upstream-Status: Denied [distribution] + +[1] https://github.com/python/cpython/pull/93760#pullrequestreview-1005365737 +--- + Makefile.pre.in | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/Makefile.pre.in b/Makefile.pre.in +index 77bf09a..6353c57 100644 +--- a/Makefile.pre.in ++++ b/Makefile.pre.in +@@ -2339,6 +2339,8 @@ python-config: $(srcdir)/Misc/python-config.in Misc/python-config.sh + @ # Substitution happens here, as the completely-expanded BINDIR + @ # is not available in configure + sed -e "s,@EXENAME@,$(EXENAME)," < $(srcdir)/Misc/python-config.in >python-config.py ++ @ # Otherwise we might get huge shebangs with native paths ++ sed -i -e '1s|^#!.*|#!/usr/bin/env python3|' python-config.py + @ # Replace makefile compat. variable references with shell script compat. ones; $(VAR) -> ${VAR} + LC_ALL=C sed -e 's,\$$(\([A-Za-z0-9_]*\)),\$$\{\1\},g' < Misc/python-config.sh >python-config + @ # On Darwin, always use the python version of the script, the shell diff --git a/meta/recipes-devtools/python/python3/0001-Do-not-use-the-shell-version-of-python-config-that-w.patch b/meta/recipes-devtools/python/python3/0001-Do-not-use-the-shell-version-of-python-config-that-w.patch deleted file mode 100644 index 8ea3f03fe0..0000000000 --- a/meta/recipes-devtools/python/python3/0001-Do-not-use-the-shell-version-of-python-config-that-w.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 04df959365e2b54d7503edf0e5534ff094284f2d Mon Sep 17 00:00:00 2001 -From: Alexander Kanavin <alex.kanavin@gmail.com> -Date: Fri, 23 Oct 2015 12:25:09 +0300 -Subject: [PATCH] Do not use the shell version of python-config that was - introduced in 3.4 - -Revert instead to the original python version: it has our tweaks and -outputs directories correctly. - -Upstream-Status: Inappropriate [oe-specific] -Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com> ---- - Makefile.pre.in | 9 +++------ - 1 file changed, 3 insertions(+), 6 deletions(-) - -diff --git a/Makefile.pre.in b/Makefile.pre.in -index 236f005..5c4337f 100644 ---- a/Makefile.pre.in -+++ b/Makefile.pre.in -@@ -1348,12 +1348,9 @@ python-config: $(srcdir)/Misc/python-config.in Misc/python-config.sh - sed -e "s,@EXENAME@,$(BINDIR)/python$(LDVERSION)$(EXE)," < $(srcdir)/Misc/python-config.in >python-config.py - # Replace makefile compat. variable references with shell script compat. ones; $(VAR) -> ${VAR} - LC_ALL=C sed -e 's,\$$(\([A-Za-z0-9_]*\)),\$$\{\1\},g' < Misc/python-config.sh >python-config -- # On Darwin, always use the python version of the script, the shell -- # version doesn't use the compiler customizations that are provided -- # in python (_osx_support.py). -- if test `uname -s` = Darwin; then \ -- cp python-config.py python-config; \ -- fi -+ # In OpenEmbedded, always use the python version of the script, the shell -+ # version is broken in multiple ways, and doesn't return correct directories -+ cp python-config.py python-config - - - # Install the include files --- -2.11.0 - diff --git a/meta/recipes-devtools/python/python3/0001-Issue-21272-Use-_sysconfigdata.py-to-initialize-dist.patch b/meta/recipes-devtools/python/python3/0001-Issue-21272-Use-_sysconfigdata.py-to-initialize-dist.patch deleted file mode 100644 index d1c92e9eed..0000000000 --- a/meta/recipes-devtools/python/python3/0001-Issue-21272-Use-_sysconfigdata.py-to-initialize-dist.patch +++ /dev/null @@ -1,66 +0,0 @@ -From bcddbf40c7f1b80336268cdddacc17369fb0ccea Mon Sep 17 00:00:00 2001 -From: Libin Dang <libin.dang@windriver.com> -Date: Tue, 11 Apr 2017 14:12:15 +0800 -Subject: [PATCH] Issue #21272: Use _sysconfigdata.py to initialize - distutils.sysconfig - -Backport upstream commit -https://github.com/python/cpython/commit/409482251b06fe75c4ee56e85ffbb4b23d934159 - -Upstream-Status: Backport - -Signed-off-by: Li Zhou <li.zhou@windriver.com> ---- - Lib/distutils/sysconfig.py | 35 ++++------------------------------- - 1 file changed, 4 insertions(+), 31 deletions(-) - -diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py -index 6d5cfd0..9925d24 100644 ---- a/Lib/distutils/sysconfig.py -+++ b/Lib/distutils/sysconfig.py -@@ -424,38 +424,11 @@ _config_vars = None - - def _init_posix(): - """Initialize the module as appropriate for POSIX systems.""" -- g = {} -- # load the installed Makefile: -- try: -- filename = get_makefile_filename() -- parse_makefile(filename, g) -- except OSError as msg: -- my_msg = "invalid Python installation: unable to open %s" % filename -- if hasattr(msg, "strerror"): -- my_msg = my_msg + " (%s)" % msg.strerror -- -- raise DistutilsPlatformError(my_msg) -- -- # load the installed pyconfig.h: -- try: -- filename = get_config_h_filename() -- with open(filename) as file: -- parse_config_h(file, g) -- except OSError as msg: -- my_msg = "invalid Python installation: unable to open %s" % filename -- if hasattr(msg, "strerror"): -- my_msg = my_msg + " (%s)" % msg.strerror -- -- raise DistutilsPlatformError(my_msg) -- -- # On AIX, there are wrong paths to the linker scripts in the Makefile -- # -- these paths are relative to the Python source, but when installed -- # the scripts are in another directory. -- if python_build: -- g['LDSHARED'] = g['BLDSHARED'] -- -+ # _sysconfigdata is generated at build time, see the sysconfig module -+ from _sysconfigdata import build_time_vars - global _config_vars -- _config_vars = g -+ _config_vars = {} -+ _config_vars.update(build_time_vars) - - - def _init_nt(): --- -1.8.3.1 - diff --git a/meta/recipes-devtools/python/python3/0001-Lib-pty.py-handle-stdin-I-O-errors-same-way-as-maste.patch b/meta/recipes-devtools/python/python3/0001-Lib-pty.py-handle-stdin-I-O-errors-same-way-as-maste.patch new file mode 100644 index 0000000000..026150f0e2 --- /dev/null +++ b/meta/recipes-devtools/python/python3/0001-Lib-pty.py-handle-stdin-I-O-errors-same-way-as-maste.patch @@ -0,0 +1,47 @@ +From f8a664cf1fc73e381d57d6927207286059744837 Mon Sep 17 00:00:00 2001 +From: Alexander Kanavin <alex@linutronix.de> +Date: Thu, 16 Sep 2021 16:35:37 +0200 +Subject: [PATCH] Lib/pty.py: handle stdin I/O errors same way as master I/O + errors + +reading stdin can throw the same I/O errors as reading from master fd does, +e.g. when running under Yocto's test harness: +====================================================================== +ERROR: test_spawn_doesnt_hang (test.test_pty.PtyTest) +---------------------------------------------------------------------- +Traceback (most recent call last): + File "/usr/lib/python3.10/test/test_pty.py", line 316, in test_spawn_doesnt_hang + pty.spawn([sys.executable, '-c', 'print("hi there")']) + File "/usr/lib/python3.10/pty.py", line 181, in spawn + _copy(master_fd, master_read, stdin_read) + File "/usr/lib/python3.10/pty.py", line 157, in _copy + data = stdin_read(STDIN_FILENO) + File "/usr/lib/python3.10/pty.py", line 132, in _read + return os.read(fd, 1024) +OSError: [Errno 5] Input/output error + +So let's treat both channels the same. + +Upstream-Status: Submitted [https://github.com/python/cpython/pull/28388] +Signed-off-by: Alexander Kanavin <alex@linutronix.de> + +--- + Lib/pty.py | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/Lib/pty.py b/Lib/pty.py +index 1d97994..fa8821b 100644 +--- a/Lib/pty.py ++++ b/Lib/pty.py +@@ -178,7 +178,10 @@ def _copy(master_fd, master_read=_read, stdin_read=_read): + i_buf = i_buf[n:] + + if stdin_avail and STDIN_FILENO in rfds: +- data = stdin_read(STDIN_FILENO) ++ try: ++ data = stdin_read(STDIN_FILENO) ++ except OSError: ++ data = b"" + if not data: + stdin_avail = False + else: diff --git a/meta/recipes-devtools/python/python3/0001-Lib-sysconfig.py-use-prefix-value-from-build-configu.patch b/meta/recipes-devtools/python/python3/0001-Lib-sysconfig.py-use-prefix-value-from-build-configu.patch new file mode 100644 index 0000000000..680254fab9 --- /dev/null +++ b/meta/recipes-devtools/python/python3/0001-Lib-sysconfig.py-use-prefix-value-from-build-configu.patch @@ -0,0 +1,32 @@ +From 71c194077bb907bfe423d3f3275f33a6c8ca0e74 Mon Sep 17 00:00:00 2001 +From: Alexander Kanavin <alex@linutronix.de> +Date: Fri, 17 Nov 2023 14:26:32 +0100 +Subject: [PATCH] Lib/sysconfig.py: use prefix value from build configuration + file + +This allows correctly substituting them for target installs using +native python. + +Upstream-Status: Inappropriate [oe-core cross builds] +Signed-off-by: Alexander Kanavin <alex@linutronix.de> + +--- + Lib/sysconfig.py | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py +index 79c0510..91ebcb6 100644 +--- a/Lib/sysconfig.py ++++ b/Lib/sysconfig.py +@@ -668,6 +668,11 @@ def _init_config_vars(): + _CONFIG_VARS['VPATH'] = sys._vpath + if os.name == 'posix': + _init_posix(_CONFIG_VARS) ++ _CONFIG_VARS['installed_base'] = _CONFIG_VARS['prefix'] ++ _CONFIG_VARS['base'] = _CONFIG_VARS['prefix'] ++ _CONFIG_VARS['installed_platbase'] = _CONFIG_VARS['prefix'] ++ _CONFIG_VARS['platbase'] = _CONFIG_VARS['prefix'] ++ _CONFIG_VARS['platlibdir'] = _CONFIG_VARS['PLATLIBDIR'] + if _HAS_USER_BASE: + # Setting 'userbase' is done below the call to the + # init function to enable using 'get_config_var' in diff --git a/meta/recipes-devtools/python/python3/0001-Makefile.pre-use-qemu-wrapper-when-gathering-profile.patch b/meta/recipes-devtools/python/python3/0001-Makefile.pre-use-qemu-wrapper-when-gathering-profile.patch new file mode 100644 index 0000000000..ee33128fa1 --- /dev/null +++ b/meta/recipes-devtools/python/python3/0001-Makefile.pre-use-qemu-wrapper-when-gathering-profile.patch @@ -0,0 +1,25 @@ +From 38278339832a57dbf5fa3ef21accaa03e2c814d7 Mon Sep 17 00:00:00 2001 +From: Alexander Kanavin <alex.kanavin@gmail.com> +Date: Wed, 30 Jan 2019 12:41:04 +0100 +Subject: [PATCH] Makefile.pre: use qemu wrapper when gathering profile data + +Upstream-Status: Inappropriate [oe-core specific] +Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com> +--- + Makefile.pre.in | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/Makefile.pre.in b/Makefile.pre.in +index dd5e69f..381feb0 100644 +--- a/Makefile.pre.in ++++ b/Makefile.pre.in +@@ -658,8 +658,7 @@ profile-run-stamp: + # enabled. + $(MAKE) profile-gen-stamp + # Next, run the profile task to generate the profile information. +- @ # FIXME: can't run for a cross build +- $(LLVM_PROF_FILE) $(RUNSHARED) ./$(BUILDPYTHON) $(PROFILE_TASK) || true ++ ./pgo-wrapper ./python -m test.regrtest --pgo test_grammar test_opcodes test_dict test_builtin test_exceptions test_types test_support || true + $(LLVM_PROF_MERGER) + # Remove profile generation binary since we are done with it. + $(MAKE) clean-retain-profile diff --git a/meta/recipes-devtools/python/python3/0001-Skip-failing-tests-due-to-load-variability-on-YP-AB.patch b/meta/recipes-devtools/python/python3/0001-Skip-failing-tests-due-to-load-variability-on-YP-AB.patch new file mode 100644 index 0000000000..197daa71a5 --- /dev/null +++ b/meta/recipes-devtools/python/python3/0001-Skip-failing-tests-due-to-load-variability-on-YP-AB.patch @@ -0,0 +1,72 @@ +From 3471e3478e0760c42e04f8046cee2367ab5706d2 Mon Sep 17 00:00:00 2001 +From: Yi Fan Yu <yifan.yu@windriver.com> +Date: Thu, 1 Apr 2021 13:08:37 -0700 +Subject: [PATCH] Skip failing tests due to load variability on YP AB + +Skip these tests until AB-INT is solved. + +[YOCTO #14296] + +Upstream-Status: Inappropriate [OE-Specific] + +Signed-off-by: Yi Fan Yu <yifan.yu@windriver.com> + +Skip two additional tests due to suspected load variability failures. + +[YOCTO #15131] +[YOCTO #15177] + +Signed-off-by: Trevor Gamblin <tgamblin@baylibre.com> +--- + Lib/test/_test_multiprocessing.py | 3 +++ + Lib/test/test_time.py | 2 ++ + 2 files changed, 5 insertions(+) + +diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py +index e42c7ab..dff5227 100644 +--- a/Lib/test/_test_multiprocessing.py ++++ b/Lib/test/_test_multiprocessing.py +@@ -682,6 +682,7 @@ class _TestProcess(BaseTestCase): + close_queue(q) + + @support.requires_resource('walltime') ++ @unittest.skip('timing related test, dependent on load') + def test_many_processes(self): + if self.TYPE == 'threads': + self.skipTest('test not appropriate for {}'.format(self.TYPE)) +@@ -2066,6 +2067,7 @@ class _TestBarrier(BaseTestCase): + except threading.BrokenBarrierError: + results.append(True) + ++ @unittest.skip('timing related test, dependent on load') + def test_timeout(self): + """ + Test wait(timeout) +@@ -5024,6 +5026,7 @@ class TestWait(unittest.TestCase): + time.sleep(period) + + @support.requires_resource('walltime') ++ @unittest.skip('timing related test, dependent on load') + def test_wait_integer(self): + from multiprocessing.connection import wait + +diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py +index 02cc3f4..51a4548 100644 +--- a/Lib/test/test_time.py ++++ b/Lib/test/test_time.py +@@ -492,6 +492,7 @@ class TimeTestCase(unittest.TestCase): + @unittest.skipIf( + support.is_wasi, "process_time not available on WASI" + ) ++ @unittest.skip('timing related test, dependent on load') + def test_process_time(self): + # process_time() should not include time spend during a sleep + start = time.process_time() +@@ -505,6 +506,7 @@ class TimeTestCase(unittest.TestCase): + self.assertTrue(info.monotonic) + self.assertFalse(info.adjustable) + ++ @unittest.skip('timing related test, dependent on load') + def test_thread_time(self): + if not hasattr(time, 'thread_time'): + if sys.platform.startswith(('linux', 'win')): diff --git a/meta/recipes-devtools/python/python3/0001-Update-test_sysconfig-for-posix_user-purelib.patch b/meta/recipes-devtools/python/python3/0001-Update-test_sysconfig-for-posix_user-purelib.patch new file mode 100644 index 0000000000..b6c6ac5a28 --- /dev/null +++ b/meta/recipes-devtools/python/python3/0001-Update-test_sysconfig-for-posix_user-purelib.patch @@ -0,0 +1,37 @@ +From 37d058e841ba3bd89b5746cc5381afb014b11581 Mon Sep 17 00:00:00 2001 +From: Wentao Zhang <wentao.zhang@windriver.com> +Date: Mon, 20 Mar 2023 13:39:52 +0800 +Subject: [PATCH] Update test_sysconfig for posix_user purelib + +Steps to trigger the failed test: +Edit local.conf to add something as follows: + BASELIB = "lib64" + IMAGE_INSTALL:append = " python3-tests". +bitbake core-image-sato +runqemu qemux86-64 nographic slirp +Reproducer: + $python3 -m test test_sysconfig + +Update test_sysconfig.test_user_similar() for the posix_user scheme: +"purelib" doesn't use sys.platlibdir. + +Upstream-Status: Inappropriate [oe-core specific] +Signed-off-by: Wentao Zhang <wentao.zhang@windriver.com> + +--- + Lib/test/test_sysconfig.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py +index b6dbf3d..5672590 100644 +--- a/Lib/test/test_sysconfig.py ++++ b/Lib/test/test_sysconfig.py +@@ -372,7 +372,7 @@ class TestSysConfig(unittest.TestCase): + expected = os.path.normpath(global_path.replace(base, user, 1)) + # bpo-44860: platlib of posix_user doesn't use sys.platlibdir, + # whereas posix_prefix does. +- if name == 'platlib': ++ if name == 'platlib' or name == 'purelib': + # Replace "/lib64/python3.11/site-packages" suffix + # with "/lib/python3.11/site-packages". + py_version_short = sysconfig.get_python_version() diff --git a/meta/recipes-devtools/python/python3/0001-cross-compile-support.patch b/meta/recipes-devtools/python/python3/0001-cross-compile-support.patch deleted file mode 100644 index 118d75ddc5..0000000000 --- a/meta/recipes-devtools/python/python3/0001-cross-compile-support.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 624c029abcc73c724020ccea9a2b4b5b5c00f2a6 Mon Sep 17 00:00:00 2001 -From: Alexander Kanavin <alex.kanavin@gmail.com> -Date: Fri, 31 Mar 2017 15:42:46 +0300 -Subject: [PATCH] cross-compile support - -We cross compile python. This patch uses tools from host/native -python instead of in-tree tools - --Khem - -Upstream-Status: Inappropriate[Configuration Specific] -Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com> ---- - Makefile.pre.in | 14 ++++++++------ - 1 file changed, 8 insertions(+), 6 deletions(-) - -diff --git a/Makefile.pre.in b/Makefile.pre.in -index a88b7d5..7cb8bb3 100644 ---- a/Makefile.pre.in -+++ b/Makefile.pre.in -@@ -221,6 +221,7 @@ LIBOBJS= @LIBOBJS@ - - PYTHON= python$(EXE) - BUILDPYTHON= python$(BUILDEXE) -+HOSTPYTHON= $(BUILDPYTHON) - - PYTHON_FOR_GEN=@PYTHON_FOR_GEN@ - PYTHON_FOR_BUILD=@PYTHON_FOR_BUILD@ -@@ -280,6 +281,7 @@ LIBFFI_INCLUDEDIR= @LIBFFI_INCLUDEDIR@ - ########################################################################## - # Parser - PGEN= Parser/pgen$(EXE) -+HOSTPGEN= $(PGEN)$(EXE) - - PSRCS= \ - Parser/acceler.c \ -@@ -510,7 +512,7 @@ build_all_generate_profile: - - run_profile_task: - : # FIXME: can't run for a cross build -- $(LLVM_PROF_FILE) $(RUNSHARED) ./$(BUILDPYTHON) $(PROFILE_TASK) || true -+ $(LLVM_PROF_FILE) $(RUNSHARED) $(HOSTPYTHON) $(PROFILE_TASK) || true - - build_all_merge_profile: - $(LLVM_PROF_MERGER) -@@ -787,7 +789,7 @@ $(IO_OBJS): $(IO_H) - - $(GRAMMAR_H): @GENERATED_COMMENT@ $(GRAMMAR_INPUT) $(PGEN) - @$(MKDIR_P) Include -- $(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C) -+ $(HOSTPGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C) - $(GRAMMAR_C): @GENERATED_COMMENT@ $(GRAMMAR_H) - touch $(GRAMMAR_C) - -@@ -976,7 +978,7 @@ $(LIBRARY_OBJS) $(MODOBJS) Programs/python.o: $(PYTHON_HEADERS) - ###################################################################### - - TESTOPTS= $(EXTRATESTOPTS) --TESTPYTHON= $(RUNSHARED) ./$(BUILDPYTHON) $(TESTPYTHONOPTS) -+TESTPYTHON= $(RUNSHARED) $(HOSTPYTHON) $(TESTPYTHONOPTS) - TESTRUNNER= $(TESTPYTHON) $(srcdir)/Tools/scripts/run_tests.py - TESTTIMEOUT= 3600 - -@@ -1468,7 +1470,7 @@ frameworkinstallstructure: $(LDLIBRARY) - fi; \ - done - $(LN) -fsn include/python$(LDVERSION) $(DESTDIR)$(prefix)/Headers -- sed 's/%VERSION%/'"`$(RUNSHARED) ./$(BUILDPYTHON) -c 'import platform; print(platform.python_version())'`"'/g' < $(RESSRCDIR)/Info.plist > $(DESTDIR)$(prefix)/Resources/Info.plist -+ sed 's/%VERSION%/'"`$(RUNSHARED) $(HOSTPYTHON) -c 'import platform; print(platform.python_version())'`"'/g' < $(RESSRCDIR)/Info.plist > $(DESTDIR)$(prefix)/Resources/Info.plist - $(LN) -fsn $(VERSION) $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Versions/Current - $(LN) -fsn Versions/Current/$(PYTHONFRAMEWORK) $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/$(PYTHONFRAMEWORK) - $(LN) -fsn Versions/Current/Headers $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Headers -@@ -1534,7 +1536,7 @@ config.status: $(srcdir)/configure - - # Run reindent on the library - reindent: -- ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/reindent.py -r $(srcdir)/Lib -+ $(HOSTPYTHON) $(srcdir)/Tools/scripts/reindent.py -r $(srcdir)/Lib - - # Rerun configure with the same options as it was run last time, - # provided the config.status script exists -@@ -1674,7 +1676,7 @@ funny: - - # Perform some verification checks on any modified files. - patchcheck: all -- $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/patchcheck.py -+ $(RUNSHARED) ./$(HOSTPYTHON) $(srcdir)/Tools/scripts/patchcheck.py - - # Dependencies - --- -2.11.0 - diff --git a/meta/recipes-devtools/python/python3/0001-gh-114492-Initialize-struct-termios-before-calling-t.patch b/meta/recipes-devtools/python/python3/0001-gh-114492-Initialize-struct-termios-before-calling-t.patch new file mode 100644 index 0000000000..8406ef30a2 --- /dev/null +++ b/meta/recipes-devtools/python/python3/0001-gh-114492-Initialize-struct-termios-before-calling-t.patch @@ -0,0 +1,26 @@ +From 439aa02f42d6e6715c172076261757fcb89a936a Mon Sep 17 00:00:00 2001 +From: "Miss Islington (bot)" + <31488909+miss-islington@users.noreply.github.com> +Date: Tue, 23 Jan 2024 23:02:02 +0100 +Subject: [PATCH] gh-114492: Initialize struct termios before calling + tcgetattr() (GH-114495) (GH-114502) + +On Alpine Linux it could leave some field non-initialized. +(cherry picked from commit d22c066b802592932f9eb18434782299e80ca42e) + +Upstream-Status: Backport [https://github.com/python/cpython/commit/386c72d9928c51aa2c855ce592bd8022da3b407f] +Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> +Signed-off-by: Khem Raj <raj.khem@gmail.com> +--- + .../next/Library/2024-01-23-21-20-40.gh-issue-114492.vKxl5o.rst | 2 ++ + 1 file changed, 2 insertions(+) + create mode 100644 Misc/NEWS.d/next/Library/2024-01-23-21-20-40.gh-issue-114492.vKxl5o.rst + +diff --git a/Misc/NEWS.d/next/Library/2024-01-23-21-20-40.gh-issue-114492.vKxl5o.rst b/Misc/NEWS.d/next/Library/2024-01-23-21-20-40.gh-issue-114492.vKxl5o.rst +new file mode 100644 +index 0000000..8df8299 +--- /dev/null ++++ b/Misc/NEWS.d/next/Library/2024-01-23-21-20-40.gh-issue-114492.vKxl5o.rst +@@ -0,0 +1,2 @@ ++Make the result of :func:`termios.tcgetattr` reproducible on Alpine Linux. ++Previously it could leave a random garbage in some fields. diff --git a/meta/recipes-devtools/python/python3/0001-h2py-Fix-issue-13032-where-it-fails-with-UnicodeDeco.patch b/meta/recipes-devtools/python/python3/0001-h2py-Fix-issue-13032-where-it-fails-with-UnicodeDeco.patch deleted file mode 100644 index dd6b24fe92..0000000000 --- a/meta/recipes-devtools/python/python3/0001-h2py-Fix-issue-13032-where-it-fails-with-UnicodeDeco.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 2f5a4c708d90fa8db21f446ae879cff79387448d Mon Sep 17 00:00:00 2001 -From: Khem Raj <raj.khem@gmail.com> -Date: Mon, 20 May 2013 21:03:16 -0700 -Subject: [PATCH] h2py: Fix issue 13032 where it fails with UnicodeDecodeError - -use utf-8 to open the files - -Signed-off-by: Khem Raj <raj.khem@gmail.com> - -Upstream-Status: Pending ---- - Tools/scripts/h2py.py | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/Tools/scripts/h2py.py b/Tools/scripts/h2py.py -index 4f871d9..a53fbe0 100755 ---- a/Tools/scripts/h2py.py -+++ b/Tools/scripts/h2py.py -@@ -69,13 +69,13 @@ def main(): - sys.stdout.write('# Generated by h2py from stdin\n') - process(sys.stdin, sys.stdout) - else: -- fp = open(filename, 'r') -+ fp = open(filename, 'r', encoding='utf-8') - outfile = os.path.basename(filename) - i = outfile.rfind('.') - if i > 0: outfile = outfile[:i] - modname = outfile.upper() - outfile = modname + '.py' -- outfp = open(outfile, 'w') -+ outfp = open(outfile, 'w', encoding='utf-8') - outfp.write('# Generated by h2py from %s\n' % filename) - filedict = {} - for dir in searchdirs: --- -1.8.1.2 - diff --git a/meta/recipes-devtools/python/python3/0001-python3-use-cc_basename-to-replace-CC-for-checking-c.patch b/meta/recipes-devtools/python/python3/0001-python3-use-cc_basename-to-replace-CC-for-checking-c.patch new file mode 100644 index 0000000000..bbeabe4389 --- /dev/null +++ b/meta/recipes-devtools/python/python3/0001-python3-use-cc_basename-to-replace-CC-for-checking-c.patch @@ -0,0 +1,120 @@ +From ababc7b1db8c406910766e11cdd04cbef7a706c9 Mon Sep 17 00:00:00 2001 +From: Changqing Li <changqing.li@windriver.com> +Date: Mon, 22 Oct 2018 15:19:51 +0800 +Subject: [PATCH] python3: use cc_basename to replace CC for checking compiler + +When working path contains "clang"/"gcc"/"icc", it might be part of $CC +because of the "--sysroot" parameter. That could cause judgement error +about clang/gcc/icc compilers. e.g. +When "icc" is containded in working path, below errors are reported when +compiling python3: +x86_64-wrs-linux-gcc: error: strict: No such file or directory +x86_64-wrs-linux-gcc: error: unrecognized command line option '-fp-model' + +Here use cc_basename to replace CC for checking compiler to avoid such +kind of issue. + +Upstream-Status: Submitted [https://github.com/python/cpython/pull/96399] + +Signed-off-by: Li Zhou <li.zhou@windriver.com> + +patch originally from Li Zhou, I just rework it to new version + +Signed-off-by: Changqing Li <changqing.li@windriver.com> +--- + configure.ac | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 384718d..5a1d58b 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -137,6 +137,7 @@ AC_CONFIG_HEADERS([pyconfig.h]) + AC_CANONICAL_HOST + AC_SUBST([build]) + AC_SUBST([host]) ++LT_INIT + + AS_VAR_IF([cross_compiling], [maybe], + [AC_MSG_ERROR([Cross compiling required --host=HOST-TUPLE and --build=ARCH])] +@@ -896,7 +897,7 @@ AC_SUBST([CXX]) + preset_cxx="$CXX" + if test -z "$CXX" + then +- case "$CC" in ++ case "$cc_basename" in + gcc) AC_PATH_TOOL([CXX], [g++], [g++], [notfound]) ;; + cc) AC_PATH_TOOL([CXX], [c++], [c++], [notfound]) ;; + clang|*/clang) AC_PATH_TOOL([CXX], [clang++], [clang++], [notfound]) ;; +@@ -1328,7 +1329,7 @@ rmdir CaseSensitiveTestDir + + case $ac_sys_system in + hp*|HP*) +- case $CC in ++ case $cc_basename in + cc|*/cc) CC="$CC -Ae";; + esac;; + esac +@@ -1854,7 +1855,7 @@ esac + ], + [AC_MSG_RESULT([no])]) + if test "$Py_LTO" = 'true' ; then +- case $CC in ++ case $cc_basename in + *clang*) + LDFLAGS_NOLTO="-fno-lto" + dnl Clang linker requires -flto in order to link objects with LTO information. +@@ -1983,7 +1984,7 @@ then + fi + fi + LLVM_PROF_ERR=no +-case $CC in ++case $cc_basename in + *clang*) + # Any changes made here should be reflected in the GCC+Darwin case below + PGO_PROF_GEN_FLAG="-fprofile-instr-generate" +@@ -2147,7 +2148,7 @@ AC_MSG_RESULT([$BOLT_APPLY_FLAGS]) + # compiler and platform. BASECFLAGS tweaks need to be made even if the + # user set OPT. + +-case $CC in ++case $cc_basename in + *clang*) + cc_is_clang=1 + ;; +@@ -2419,7 +2420,7 @@ yes) + + # ICC doesn't recognize the option, but only emits a warning + ## XXX does it emit an unused result warning and can it be disabled? +- AS_CASE([$CC], ++ AS_CASE([$cc_basename], + [*icc*], [ac_cv_disable_unused_result_warning=no] + [PY_CHECK_CC_WARNING([disable], [unused-result])]) + AS_VAR_IF([ac_cv_disable_unused_result_warning], [yes], +@@ -2665,7 +2666,7 @@ yes) + ;; + esac + +-case "$CC" in ++case "$cc_basename" in + *mpicc*) + CFLAGS_NODIST="$CFLAGS_NODIST" + ;; +@@ -3482,7 +3483,7 @@ then + then + LINKFORSHARED="-Wl,--export-dynamic" + fi;; +- SunOS/5*) case $CC in ++ SunOS/5*) case $cc_basename in + *gcc*) + if $CC -Xlinker --help 2>&1 | grep export-dynamic >/dev/null + then +@@ -6803,7 +6804,7 @@ if test "$ac_cv_gcc_asm_for_x87" = yes; then + # Some versions of gcc miscompile inline asm: + # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46491 + # http://gcc.gnu.org/ml/gcc/2010-11/msg00366.html +- case $CC in ++ case $cc_basename in + *gcc*) + AC_MSG_CHECKING([for gcc ipa-pure-const bug]) + saved_cflags="$CFLAGS" diff --git a/meta/recipes-devtools/python/python3/0001-skip-no_stdout_fileno-test-due-to-load-variability.patch b/meta/recipes-devtools/python/python3/0001-skip-no_stdout_fileno-test-due-to-load-variability.patch new file mode 100644 index 0000000000..2d7bca6a77 --- /dev/null +++ b/meta/recipes-devtools/python/python3/0001-skip-no_stdout_fileno-test-due-to-load-variability.patch @@ -0,0 +1,29 @@ +From 217cea231462e7703e8c9ea39c0a6833f799a420 Mon Sep 17 00:00:00 2001 +From: Trevor Gamblin <tgamblin@baylibre.com> +Date: Fri, 15 Sep 2023 08:48:33 -0400 +Subject: [PATCH] skip no_stdout_fileno test due to load variability + +Skip test_input_no_stdout_fileno so that it doesn't fail on systems +under heavy load. + +Upstream-Status: Inappropriate [OE-Specific] + +[YOCTO #15210] + +Signed-off-by: Trevor Gamblin <tgamblin@baylibre.com> +--- + Lib/test/test_builtin.py | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py +index 4d03c46..b329b7a 100644 +--- a/Lib/test/test_builtin.py ++++ b/Lib/test/test_builtin.py +@@ -2326,6 +2326,7 @@ class PtyTests(unittest.TestCase): + # Check stdin/stdout error handler is used when invoking PyOS_Readline() + self.check_input_tty("prompté", b"quux\xe9", "ascii") + ++ @unittest.skip("Test may fail under heavy load") + def test_input_no_stdout_fileno(self): + # Issue #24402: If stdin is the original terminal but stdout.fileno() + # fails, do not use the original stdout file descriptor diff --git a/meta/recipes-devtools/python/python3/0001-sysconfig.py-use-platlibdir-also-for-purelib.patch b/meta/recipes-devtools/python/python3/0001-sysconfig.py-use-platlibdir-also-for-purelib.patch new file mode 100644 index 0000000000..fc52fdac26 --- /dev/null +++ b/meta/recipes-devtools/python/python3/0001-sysconfig.py-use-platlibdir-also-for-purelib.patch @@ -0,0 +1,28 @@ +From a5d429a0e1a4809c1ded7be7e45dcabeb82c53d8 Mon Sep 17 00:00:00 2001 +From: Alexander Kanavin <alex@linutronix.de> +Date: Sun, 12 Sep 2021 21:44:36 +0200 +Subject: [PATCH] sysconfig.py: use platlibdir also for purelib + +This is needed in multilib configurations where hardcoding 'lib' +is not correct. + +Upstream-Status: Inappropriate [oe-core specific] +Signed-off-by: Alexander Kanavin <alex@linutronix.de> + +--- + Lib/sysconfig.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py +index 122d441..79c0510 100644 +--- a/Lib/sysconfig.py ++++ b/Lib/sysconfig.py +@@ -28,7 +28,7 @@ _INSTALL_SCHEMES = { + 'posix_prefix': { + 'stdlib': '{installed_base}/{platlibdir}/python{py_version_short}', + 'platstdlib': '{platbase}/{platlibdir}/python{py_version_short}', +- 'purelib': '{base}/lib/python{py_version_short}/site-packages', ++ 'purelib': '{base}/{platlibdir}/python{py_version_short}/site-packages', + 'platlib': '{platbase}/{platlibdir}/python{py_version_short}/site-packages', + 'include': + '{installed_base}/include/python{py_version_short}{abiflags}', diff --git a/meta/recipes-devtools/python/python3/0001-test_ctypes.test_find-skip-without-tools-sdk.patch b/meta/recipes-devtools/python/python3/0001-test_ctypes.test_find-skip-without-tools-sdk.patch new file mode 100644 index 0000000000..b4fe946cba --- /dev/null +++ b/meta/recipes-devtools/python/python3/0001-test_ctypes.test_find-skip-without-tools-sdk.patch @@ -0,0 +1,34 @@ +From b64c131a576a4b4f821514e711ab91b1394fb4ff Mon Sep 17 00:00:00 2001 +From: Tim Orling <timothy.t.orling@intel.com> +Date: Fri, 18 Jun 2021 11:56:50 -0700 +Subject: [PATCH] test_ctypes.test_find: skip without tools-sdk + +These tests need full packagegroup-core-buildessential, the +easiest way to dynamically check for that is looking for +'tools-sdk' in IMAGE_FEATURES. + +Upstream-Status: Inappropriate [oe-specific] + +Signed-off-by: Tim Orling <timothy.t.orling@intel.com> + +--- + Lib/test/test_ctypes/test_find.py | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/Lib/test/test_ctypes/test_find.py b/Lib/test/test_ctypes/test_find.py +index 1ff9d01..59def26 100644 +--- a/Lib/test/test_ctypes/test_find.py ++++ b/Lib/test/test_ctypes/test_find.py +@@ -113,10 +113,12 @@ class FindLibraryLinux(unittest.TestCase): + # LD_LIBRARY_PATH) + self.assertEqual(find_library(libname), 'lib%s.so' % libname) + ++ @unittest.skip("Needs IMAGE_FEATURE += \"tools-sdk\"") + 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.skip("Needs IMAGE_FEATURE += \"tools-sdk\"") + 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/meta/recipes-devtools/python/python3/0001-test_locale.py-correct-the-test-output-format.patch b/meta/recipes-devtools/python/python3/0001-test_locale.py-correct-the-test-output-format.patch new file mode 100644 index 0000000000..410a9fc7f1 --- /dev/null +++ b/meta/recipes-devtools/python/python3/0001-test_locale.py-correct-the-test-output-format.patch @@ -0,0 +1,46 @@ +From ef5728f0af14da5c9f80b0f038fe5bf6d44cb0e9 Mon Sep 17 00:00:00 2001 +From: Mingli Yu <mingli.yu@windriver.com> +Date: Mon, 5 Aug 2019 15:57:39 +0800 +Subject: [PATCH] test_locale.py: correct the test output format + +Before this patch: + # python3 -m test -v test_locale + [snip] + test_getsetlocale_issue1813 (test.test_locale.TestMiscellaneous) ... testing with ('tr_TR', 'ISO8859-9') ok + [snip] + + After this patch: + # python3 -m test -v test_locale + [snip] + test_getsetlocale_issue1813 (test.test_locale.TestMiscellaneous) ... testing with ('tr_TR', 'ISO8859-9')... ok + [snip] + + Make the test ended with "... ok" is common in python + unittest world, we should make it keep consistent + with other test cases in case it may be ignored to + record in the report if we use the common filter + "... ok". + +Upstream-Status: Submitted [https://github.com/python/cpython/pull/15132] + +Rebased for 3.9.4, still not accepted upstream Signed-off-by: Alejandro Hernandez <alejandro@enedino.org> + +Signed-off-by: Mingli Yu <mingli.yu@windriver.com> + +--- + Lib/test/test_locale.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py +index b0d7998..cb12153 100644 +--- a/Lib/test/test_locale.py ++++ b/Lib/test/test_locale.py +@@ -557,7 +557,7 @@ class TestMiscellaneous(unittest.TestCase): + self.skipTest('test needs Turkish locale') + loc = locale.getlocale(locale.LC_CTYPE) + if verbose: +- print('testing with %a' % (loc,), end=' ', flush=True) ++ print('testing with %a...' % (loc,), end=' ', flush=True) + try: + locale.setlocale(locale.LC_CTYPE, loc) + except locale.Error as exc: diff --git a/meta/recipes-devtools/python/python3/0001-test_storlines-skip-due-to-load-variability.patch b/meta/recipes-devtools/python/python3/0001-test_storlines-skip-due-to-load-variability.patch new file mode 100644 index 0000000000..0d0eb08459 --- /dev/null +++ b/meta/recipes-devtools/python/python3/0001-test_storlines-skip-due-to-load-variability.patch @@ -0,0 +1,30 @@ +From dc69a1afdb3ba619705ff71e14f19ed3142e422f Mon Sep 17 00:00:00 2001 +From: Trevor Gamblin <tgamblin@baylibre.com> +Date: Fri, 6 Oct 2023 10:59:44 -0400 +Subject: [PATCH] test_storlines: skip due to load variability + +This is yet another test that intermittently fails on the Yocto AB when +a worker is under heavy load, so skip it during testing. + +Upstream-Status: Inappropriate [OE-Specific] + +[YOCTO #14933] + +Signed-off-by: Trevor Gamblin <tgamblin@baylibre.com> + +--- + Lib/test/test_ftplib.py | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py +index 2f191ea..dc29346 100644 +--- a/Lib/test/test_ftplib.py ++++ b/Lib/test/test_ftplib.py +@@ -626,6 +626,7 @@ class TestFTPClass(TestCase): + self.client.storbinary('stor', f, rest=r) + self.assertEqual(self.server.handler_instance.rest, str(r)) + ++ @unittest.skip('timing related test, dependent on load') + def test_storlines(self): + data = RETR_DATA.replace('\r\n', '\n').encode(self.client.encoding) + f = io.BytesIO(data) diff --git a/meta/recipes-devtools/python/python3/0020-configure.ac-setup.py-do-not-add-a-curses-include-pa.patch b/meta/recipes-devtools/python/python3/0020-configure.ac-setup.py-do-not-add-a-curses-include-pa.patch new file mode 100644 index 0000000000..0661249bfd --- /dev/null +++ b/meta/recipes-devtools/python/python3/0020-configure.ac-setup.py-do-not-add-a-curses-include-pa.patch @@ -0,0 +1,33 @@ +From d0205c60d08f51d84bd8ddc07a57e8c71710fdad Mon Sep 17 00:00:00 2001 +From: Alexander Kanavin <alex@linutronix.de> +Date: Fri, 17 Nov 2023 14:16:40 +0100 +Subject: [PATCH] configure.ac: do not add a curses include path from the host + +This leads to host contamination, and particularly can cause +curses modules to fail at runtime if the host curses is configured +differently to native curses (observed on current OpenSuse Tumbleweed +as dnf failures). + +Upstream-Status: Inappropriate [oe-core specific] +Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com> +--- + configure.ac | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/configure.ac b/configure.ac +index c49cd4f..affdedf 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -6508,12 +6508,6 @@ AS_VAR_IF([have_panel], [no], [ + AC_MSG_RESULT([$have_panel (CFLAGS: $PANEL_CFLAGS, LIBS: $PANEL_LIBS)]) + ]) + +-# first curses header check +-ac_save_cppflags="$CPPFLAGS" +-if test "$cross_compiling" = no; then +- CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw" +-fi +- + # On Solaris, term.h requires curses.h + AC_CHECK_HEADERS([term.h], [], [], [ + #ifdef HAVE_CURSES_H diff --git a/meta/recipes-devtools/python/python3/03-fix-tkinter-detection.patch b/meta/recipes-devtools/python/python3/03-fix-tkinter-detection.patch deleted file mode 100644 index fddfd2b2f6..0000000000 --- a/meta/recipes-devtools/python/python3/03-fix-tkinter-detection.patch +++ /dev/null @@ -1,42 +0,0 @@ -Upstream-Status: Inappropriate [embedded specific] - -# We need to supply STAGING_INCDIR here, otherwise the Tk headers -# will not be found. -# Signed-Off: Michael 'Mickey' Lauer <mickey@vanille.de> - -Index: Python-3.3.0rc2/setup.py -=================================================================== ---- Python-3.3.0rc2.orig/setup.py 2012-09-20 15:24:14.009124003 -0700 -+++ Python-3.3.0rc2/setup.py 2012-09-20 15:25:08.449124963 -0700 -@@ -1620,7 +1620,7 @@ - dotversion = dotversion[:-1] + '.' + dotversion[-1] - tcl_include_sub = [] - tk_include_sub = [] -- for dir in inc_dirs: -+ for dir in [os.getenv("STAGING_INCDIR")]: - tcl_include_sub += [dir + os.sep + "tcl" + dotversion] - tk_include_sub += [dir + os.sep + "tk" + dotversion] - tk_include_sub += tcl_include_sub -@@ -1639,22 +1639,6 @@ - if dir not in include_dirs: - include_dirs.append(dir) - -- # Check for various platform-specific directories -- if host_platform == 'sunos5': -- include_dirs.append('/usr/openwin/include') -- added_lib_dirs.append('/usr/openwin/lib') -- elif os.path.exists('/usr/X11R6/include'): -- include_dirs.append('/usr/X11R6/include') -- added_lib_dirs.append('/usr/X11R6/lib64') -- added_lib_dirs.append('/usr/X11R6/lib') -- elif os.path.exists('/usr/X11R5/include'): -- include_dirs.append('/usr/X11R5/include') -- added_lib_dirs.append('/usr/X11R5/lib') -- else: -- # Assume default location for X11 -- include_dirs.append('/usr/X11/include') -- added_lib_dirs.append('/usr/X11/lib') -- - # If Cygwin, then verify that X is installed before proceeding - if host_platform == 'cygwin': - x11_inc = find_file('X11/Xlib.h', [], include_dirs) diff --git a/meta/recipes-devtools/python/python3/030-fixup-include-dirs.patch b/meta/recipes-devtools/python/python3/030-fixup-include-dirs.patch deleted file mode 100644 index 6beac7b805..0000000000 --- a/meta/recipes-devtools/python/python3/030-fixup-include-dirs.patch +++ /dev/null @@ -1,33 +0,0 @@ -Do not hardcode /usr into include paths when cross compiling - --Khem - -Upstream-Status: Pending - ---- - setup.py | 15 ++------------- - 1 file changed, 2 insertions(+), 13 deletions(-) - -Index: Python-3.3.2/setup.py -=================================================================== ---- Python-3.3.2.orig/setup.py -+++ Python-3.3.2/setup.py -@@ -444,7 +444,8 @@ class PyBuildExt(build_ext): - # only change this for cross builds for 3.3, issues on Mageia - if cross_compiling: - self.add_gcc_paths() -- self.add_multiarch_paths() -+ if not cross_compiling: -+ self.add_multiarch_paths() - - # Add paths specified in the environment variables LDFLAGS and - # CPPFLAGS for header and library files. -@@ -480,7 +481,7 @@ class PyBuildExt(build_ext): - for directory in reversed(options.dirs): - add_dir_to_list(dir_list, directory) - -- if os.path.normpath(sys.base_prefix) != '/usr' \ -+ if not cross_compiling and os.path.normpath(sys.base_prefix) != '/usr' \ - and not sysconfig.get_config_var('PYTHONFRAMEWORK'): - # OSX note: Don't add LIBDIR and INCLUDEDIR to building a framework - # (PYTHONFRAMEWORK is set) to avoid # linking problems when diff --git a/meta/recipes-devtools/python/python3/070-dont-clean-ipkg-install.patch b/meta/recipes-devtools/python/python3/070-dont-clean-ipkg-install.patch deleted file mode 100644 index 789929b715..0000000000 --- a/meta/recipes-devtools/python/python3/070-dont-clean-ipkg-install.patch +++ /dev/null @@ -1,36 +0,0 @@ -consider opkg directories when cleaning up - --Khem - -Upstream-Status: Inappropriate [OE specific] - ---- - Makefile.pre.in | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/Makefile.pre.in -+++ b/Makefile.pre.in -@@ -1306,8 +1306,8 @@ touch: - # Sanitation targets -- clean leaves libraries, executables and tags - # files, which clobber removes as well - pycremoval: -- -find $(srcdir) -depth -name '__pycache__' -exec rm -rf {} ';' -- -find $(srcdir) -name '*.py[co]' -exec rm -f {} ';' -+ -find $(srcdir) ! -path './ipkg-install/*' -depth -name '__pycache__' -exec rm -rf {} ';' -+ -find $(srcdir) ! -path './ipkg-install/*' -name '*.py[co]' -exec rm -f {} ';' - - rmtestturds: - -rm -f *BAD *GOOD *SKIPPED -@@ -1321,9 +1321,9 @@ docclean: - -rm -rf Doc/tools/sphinx Doc/tools/pygments Doc/tools/docutils - - clean: pycremoval -- find . -name '*.[oa]' -exec rm -f {} ';' -- find . -name '*.s[ol]' -exec rm -f {} ';' -- find . -name '*.so.[0-9]*.[0-9]*' -exec rm -f {} ';' -+ find . ! -path './ipkg-install/*' -name '*.[oa]' -exec rm -f {} ';' -+ find . ! -path './ipkg-install/*' -name '*.s[ol]' -exec rm -f {} ';' -+ find . ! -path './ipkg-install/*' -name '*.so.[0-9]*.[0-9]*' -exec rm -f {} ';' - find build -name 'fficonfig.h' -exec rm -f {} ';' || true - find build -name 'fficonfig.py' -exec rm -f {} ';' || true - -rm -f Lib/lib2to3/*Grammar*.pickle diff --git a/meta/recipes-devtools/python/python3/080-distutils-dont_adjust_files.patch b/meta/recipes-devtools/python/python3/080-distutils-dont_adjust_files.patch deleted file mode 100644 index b96419a638..0000000000 --- a/meta/recipes-devtools/python/python3/080-distutils-dont_adjust_files.patch +++ /dev/null @@ -1,92 +0,0 @@ -do not "adjust" python files before copying - --Khem - -Upstream-Status: Inappropriate [Embedded-Specific] - ---- - Lib/distutils/command/build_scripts.py | 43 +++------------------------------ - 1 file changed, 4 insertions(+), 39 deletions(-) - ---- a/Lib/distutils/command/build_scripts.py -+++ b/Lib/distutils/command/build_scripts.py -@@ -51,10 +51,7 @@ class build_scripts(Command): - - - def copy_scripts(self): -- """Copy each script listed in 'self.scripts'; if it's marked as a -- Python script in the Unix way (first line matches 'first_line_re', -- ie. starts with "\#!" and contains "python"), then adjust the first -- line to refer to the current Python interpreter as we copy. -+ """Copy each script listed in 'self.scripts' - """ - self.mkpath(self.build_dir) - outfiles = [] -@@ -78,64 +75,10 @@ class build_scripts(Command): - if not self.dry_run: - raise - f = None -- else: -- encoding, lines = tokenize.detect_encoding(f.readline) -- f.seek(0) -- first_line = f.readline() -- if not first_line: -- self.warn("%s is an empty file (skipping)" % script) -- continue -- -- match = first_line_re.match(first_line) -- if match: -- adjust = True -- post_interp = match.group(1) or b'' -- -- if adjust: -- log.info("copying and adjusting %s -> %s", script, -- self.build_dir) -- updated_files.append(outfile) -- if not self.dry_run: -- if not sysconfig.python_build: -- executable = self.executable -- else: -- executable = os.path.join( -- sysconfig.get_config_var("BINDIR"), -- "python%s%s" % (sysconfig.get_config_var("VERSION"), -- sysconfig.get_config_var("EXE"))) -- executable = os.fsencode(executable) -- shebang = b"#!" + executable + post_interp + b"\n" -- # Python parser starts to read a script using UTF-8 until -- # it gets a #coding:xxx cookie. The shebang has to be the -- # first line of a file, the #coding:xxx cookie cannot be -- # written before. So the shebang has to be decodable from -- # UTF-8. -- try: -- shebang.decode('utf-8') -- except UnicodeDecodeError: -- raise ValueError( -- "The shebang ({!r}) is not decodable " -- "from utf-8".format(shebang)) -- # If the script is encoded to a custom encoding (use a -- # #coding:xxx cookie), the shebang has to be decodable from -- # the script encoding too. -- try: -- shebang.decode(encoding) -- except UnicodeDecodeError: -- raise ValueError( -- "The shebang ({!r}) is not decodable " -- "from the script encoding ({})" -- .format(shebang, encoding)) -- with open(outfile, "wb") as outf: -- outf.write(shebang) -- outf.writelines(f.readlines()) -- if f: -- f.close() -- else: -- if f: -+ if f: - f.close() -- updated_files.append(outfile) -- self.copy_file(script, outfile) -+ updated_files.append(outfile) -+ self.copy_file(script, outfile) - - if os.name == 'posix': - for file in outfiles: diff --git a/meta/recipes-devtools/python/python3/12-distutils-prefix-is-inside-staging-area.patch b/meta/recipes-devtools/python/python3/12-distutils-prefix-is-inside-staging-area.patch deleted file mode 100644 index c53ec0cfc8..0000000000 --- a/meta/recipes-devtools/python/python3/12-distutils-prefix-is-inside-staging-area.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 7630ab22578746d3d790d0598c0d279cf7afed97 Mon Sep 17 00:00:00 2001 -From: Khem Raj <raj.khem@gmail.com> -Date: Tue, 14 May 2013 15:00:26 -0700 -Subject: [PATCH 01/20] python3: Add target and native recipes - -Upstream-Status: Inappropriate [embedded specific] - -02/2015 Rebased for Python 3.4.2 - -# The proper prefix is inside our staging area. -# Signed-Off: Michael 'Mickey' Lauer <mickey@vanille-media.de> -# Signed-off-by: Phil Blundell <philb@gnu.org> -# Signed-off-by: Khem Raj <raj.khem@gmail.com> -# Signed-off-by: Alejandro Hernandez <alejandro.hernandez@linux.intel.com> - ---- - Lib/distutils/sysconfig.py | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py -index 573724d..390c485 100644 ---- a/Lib/distutils/sysconfig.py -+++ b/Lib/distutils/sysconfig.py -@@ -84,7 +84,9 @@ def get_python_inc(plat_specific=0, prefix=None): - If 'prefix' is supplied, use it instead of sys.base_prefix or - sys.base_exec_prefix -- i.e., ignore 'plat_specific'. - """ -- if prefix is None: -+ if prefix is None and os.environ['STAGING_INCDIR'] != "": -+ prefix = os.environ['STAGING_INCDIR'].rstrip('include') -+ elif prefix is None: - prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX - if os.name == "posix": - if python_build: -@@ -125,6 +127,10 @@ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): - If 'prefix' is supplied, use it instead of sys.base_prefix or - sys.base_exec_prefix -- i.e., ignore 'plat_specific'. - """ -+ lib_basename = os.environ['STAGING_LIBDIR'].split('/')[-1] -+ if prefix is None and os.environ['STAGING_LIBDIR'] != "": -+ prefix = os.environ['STAGING_LIBDIR'].rstrip(lib_basename) -+ - if prefix is None: - if standard_lib: - prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX -@@ -133,7 +139,7 @@ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): - - if os.name == "posix": - libpython = os.path.join(prefix, -- "lib", "python" + get_python_version()) -+ lib_basename, "python" + get_python_version()) - if standard_lib: - return libpython - else: --- -2.8.0.rc3 - diff --git a/meta/recipes-devtools/python/python3/130-readline-setup.patch b/meta/recipes-devtools/python/python3/130-readline-setup.patch deleted file mode 100644 index c805652d69..0000000000 --- a/meta/recipes-devtools/python/python3/130-readline-setup.patch +++ /dev/null @@ -1,55 +0,0 @@ -package python-readline - --Khem - -Upstream-Status: Inappropriate [Embedded Specific] - ---- a/setup.py -+++ b/setup.py -@@ -666,45 +666,7 @@ class PyBuildExt(build_ext): - # readline - do_readline = self.compiler.find_library_file(lib_dirs, 'readline') - readline_termcap_library = "" -- curses_library = "" -- # Cannot use os.popen here in py3k. -- tmpfile = os.path.join(self.build_temp, 'readline_termcap_lib') -- if not os.path.exists(self.build_temp): -- os.makedirs(self.build_temp) -- # Determine if readline is already linked against curses or tinfo. -- if do_readline: -- if cross_compiling: -- ret = os.system("%s -d %s | grep '(NEEDED)' > %s" \ -- % (sysconfig.get_config_var('READELF'), -- do_readline, tmpfile)) -- elif find_executable('ldd'): -- ret = os.system("ldd %s > %s" % (do_readline, tmpfile)) -- else: -- ret = 256 -- if ret >> 8 == 0: -- with open(tmpfile) as fp: -- for ln in fp: -- if 'curses' in ln: -- readline_termcap_library = re.sub( -- r'.*lib(n?cursesw?)\.so.*', r'\1', ln -- ).rstrip() -- break -- # termcap interface split out from ncurses -- if 'tinfo' in ln: -- readline_termcap_library = 'tinfo' -- break -- if os.path.exists(tmpfile): -- os.unlink(tmpfile) -- # Issue 7384: If readline is already linked against curses, -- # use the same library for the readline and curses modules. -- if 'curses' in readline_termcap_library: -- curses_library = readline_termcap_library -- elif self.compiler.find_library_file(lib_dirs, 'ncursesw'): -- curses_library = 'ncursesw' -- elif self.compiler.find_library_file(lib_dirs, 'ncurses'): -- curses_library = 'ncurses' -- elif self.compiler.find_library_file(lib_dirs, 'curses'): -- curses_library = 'curses' -+ curses_library = "ncurses" - - if host_platform == 'darwin': - os_release = int(os.uname()[2].split('.')[0]) diff --git a/meta/recipes-devtools/python/python3/150-fix-setupterm.patch b/meta/recipes-devtools/python/python3/150-fix-setupterm.patch deleted file mode 100644 index 78d7c78670..0000000000 --- a/meta/recipes-devtools/python/python3/150-fix-setupterm.patch +++ /dev/null @@ -1,17 +0,0 @@ -Fix warning with newer compiler - --Khem - -Upstream-Status: Pending - ---- a/Modules/_cursesmodule.c -+++ b/Modules/_cursesmodule.c -@@ -116,7 +116,7 @@ char *PyCursesVersion = "2.2"; - #defines many common symbols (such as "lines") which breaks the - curses module in other ways. So the code will just specify - explicit prototypes here. */ --extern int setupterm(char *,int,int *); -+//extern int setupterm(char *,int,int *); - #ifdef __sgi - #include <term.h> - #endif diff --git a/meta/recipes-devtools/python/python3/Fix-29519-weakref-spewing-exceptions-during-interp-f.patch b/meta/recipes-devtools/python/python3/Fix-29519-weakref-spewing-exceptions-during-interp-f.patch deleted file mode 100644 index 7217c6edea..0000000000 --- a/meta/recipes-devtools/python/python3/Fix-29519-weakref-spewing-exceptions-during-interp-f.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 62dcf34987b680e95873eb947b3f4d802199c667 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C5=81ukasz=20Langa?= <lukasz@langa.pl> -Date: Fri, 10 Feb 2017 00:14:55 -0800 -Subject: [PATCH] Fix #29519: weakref spewing exceptions during interp - finalization - -commit 9cd7e17640a49635d1c1f8c2989578a8fc2c1de6 -from https://github.com/python/cpython - -Upstream-Status: Backport - -Signed-off-by: Lukasz Langa <lukasz@langa.pl> ---- - Lib/weakref.py | 4 ++-- - Misc/NEWS | 3 +++ - 2 files changed, 5 insertions(+), 2 deletions(-) - -diff --git a/Lib/weakref.py b/Lib/weakref.py -index aaebd0c..787e33a 100644 ---- a/Lib/weakref.py -+++ b/Lib/weakref.py -@@ -106,7 +106,7 @@ class WeakValueDictionary(collections.MutableMapping): - self, *args = args - if len(args) > 1: - raise TypeError('expected at most 1 arguments, got %d' % len(args)) -- def remove(wr, selfref=ref(self)): -+ def remove(wr, selfref=ref(self), _atomic_removal=_remove_dead_weakref): - self = selfref() - if self is not None: - if self._iterating: -@@ -114,7 +114,7 @@ class WeakValueDictionary(collections.MutableMapping): - else: - # Atomic removal is necessary since this function - # can be called asynchronously by the GC -- _remove_dead_weakref(d, wr.key) -+ _atomic_removal(d, wr.key) - self._remove = remove - # A list of keys to be removed - self._pending_removals = [] -diff --git a/Misc/NEWS b/Misc/NEWS -index 41cfdba..6d89f52 100644 ---- a/Misc/NEWS -+++ b/Misc/NEWS -@@ -5719,6 +5719,9 @@ Core and Builtins - Library - ------- - -+- Issue #29519: Fix weakref spewing exceptions during interpreter shutdown -+ when used with a rare combination of multiprocessing and custom codecs. -+ - - Issue #20154: Deadlock in asyncio.StreamReader.readexactly(). - - - Issue #16113: Remove sha3 module again. --- -2.7.4 - diff --git a/meta/recipes-devtools/python/python3/avoid-ncursesw-include-path.patch b/meta/recipes-devtools/python/python3/avoid-ncursesw-include-path.patch deleted file mode 100644 index f29ae53371..0000000000 --- a/meta/recipes-devtools/python/python3/avoid-ncursesw-include-path.patch +++ /dev/null @@ -1,21 +0,0 @@ -Upstream-Status: Pending - -We should make sure that sysroot is used by gcc instead of assuming -hardcoded locations for include paths - - -Signed-off-by: Khem Raj <raj.khem@gmail.com> - -Index: Python-3.4.2/configure.ac -=================================================================== ---- Python-3.4.2.orig/configure.ac -+++ Python-3.4.2/configure.ac -@@ -4434,7 +4434,7 @@ fi - - # first curses header check - ac_save_cppflags="$CPPFLAGS" --CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw" -+CPPFLAGS="$CPPFLAGS -I=/usr/include/ncursesw" - - AC_CHECK_HEADERS(curses.h ncurses.h) - diff --git a/meta/recipes-devtools/python/python3/avoid_warning_about_tkinter.patch b/meta/recipes-devtools/python/python3/avoid_warning_about_tkinter.patch deleted file mode 100644 index 3347321fde..0000000000 --- a/meta/recipes-devtools/python/python3/avoid_warning_about_tkinter.patch +++ /dev/null @@ -1,39 +0,0 @@ -_tkinter module needs tk module along with tcl. tk is not yet integrated -in yocto so we skip the check for this module. -Avoid a warning by not adding this module to missing variable. - -Upstream-Status: Inappropriate [distribution] - -Also simply disable the tk module since its not in DEPENDS. -Signed-off-by: Andrei Gherzan <andrei@gherzan.ro> - -Index: Python-2.7.2/setup.py -=================================================================== ---- Python-2.7.2.orig/setup.py 2012-04-05 23:18:38.500136647 +0300 -+++ Python-2.7.2/setup.py 2012-04-05 23:19:35.888134969 +0300 -@@ -1634,8 +1634,10 @@ - # Call the method for detecting whether _tkinter can be compiled - self.detect_tkinter(inc_dirs, lib_dirs) - -- if '_tkinter' not in [e.name for e in self.extensions]: -- missing.append('_tkinter') -+ # tkinter module will not be avalaible as yocto -+ # doesn't have tk integrated (yet) -+ #if '_tkinter' not in [e.name for e in self.extensions]: -+ # missing.append('_tkinter') - - return missing - -diff --git Python-3.5.1.orig/setup.py Python-3.5.1/setup.py -index b4633b9..d7588c0 100644 ---- Python-3.5.1.orig/setup.py -+++ Python-3.5.1/setup.py -@@ -1536,7 +1536,7 @@ class PyBuildExt(build_ext): - self.extensions.extend(exts) - - # Call the method for detecting whether _tkinter can be compiled -- self.detect_tkinter(inc_dirs, lib_dirs) -+ # self.detect_tkinter(inc_dirs, lib_dirs) - - # tkinter module will not be avalaible as yocto - # doesn't have tk integrated (yet) diff --git a/meta/recipes-devtools/python/python3/cgi_py.patch b/meta/recipes-devtools/python/python3/cgi_py.patch index de504f9dcf..8262c88e73 100644 --- a/meta/recipes-devtools/python/python3/cgi_py.patch +++ b/meta/recipes-devtools/python/python3/cgi_py.patch @@ -1,11 +1,20 @@ -Lib/cgi.py: Update the script as mentioned in the comment +From a56778372fe8dc7c42f5ffd911d89498c22dd064 Mon Sep 17 00:00:00 2001 +From: Mark Hatle <mark.hatle@windriver.com> +Date: Wed, 21 Sep 2011 20:55:33 -0500 +Subject: [PATCH] Lib/cgi.py: Update the script as mentioned in the comment Upstream-Status: Inappropriate [distribution] Signed-off-by: Mark Hatle <mark.hatle@windriver.com> ---- Python-2.6.6/Lib/cgi.py.orig 2010-08-01 22:14:27.000000000 -0500 -+++ Python-2.6.6/Lib/cgi.py 2011-09-21 15:28:40.478208631 -0500 +--- + Lib/cgi.py | 11 +---------- + 1 file changed, 1 insertion(+), 10 deletions(-) + +diff --git a/Lib/cgi.py b/Lib/cgi.py +index 8787567..ebe8652 100755 +--- a/Lib/cgi.py ++++ b/Lib/cgi.py @@ -1,13 +1,4 @@ -#! /usr/local/bin/python - diff --git a/meta/recipes-devtools/python/python3/check_build_completeness.py b/meta/recipes-devtools/python/python3/check_build_completeness.py new file mode 100755 index 0000000000..a1eace3f57 --- /dev/null +++ b/meta/recipes-devtools/python/python3/check_build_completeness.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python3 +import sys +logfile = open(sys.argv[1]).read() + +necessary_bits = logfile.find("The necessary bits to build these optional modules were not found") +to_find_bits = logfile.find("To find the necessary bits, look in setup.py in detect_modules() for the module's name.") +if necessary_bits != -1: + print("%s" %(logfile[necessary_bits:to_find_bits])) + +failed_to_build = logfile.find("Failed to build these modules:") +if failed_to_build != -1: + failed_to_build_end = logfile.find("\n\n", failed_to_build) + print("%s" %(logfile[failed_to_build:failed_to_build_end])) + +if necessary_bits != -1 or failed_to_build != -1: + sys.exit(1) + diff --git a/meta/recipes-devtools/python/python3/configure.ac-fix-LIBPL.patch b/meta/recipes-devtools/python/python3/configure.ac-fix-LIBPL.patch deleted file mode 100644 index 97214f9aa4..0000000000 --- a/meta/recipes-devtools/python/python3/configure.ac-fix-LIBPL.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 7c4f8d87473d6238c120ec6031b58f83a17a39a5 Mon Sep 17 00:00:00 2001 -From: Robert Yang <liezhi.yang@windriver.com> -Date: Mon, 28 Dec 2015 22:52:06 -0800 -Subject: [PATCH] configure.ac: fix LIBPL - -Use LIBDIR rather than prefix/lib, so that it would work when lib64. - -Upstream-Status: Pending - -Signed-off-by: Robert Yang <liezhi.yang@windriver.com> ---- - configure.ac | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index 63aef8e..aefb27f 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -4366,7 +4366,7 @@ AC_MSG_RESULT($LDVERSION) - - dnl define LIBPL after ABIFLAGS and LDVERSION is defined. - AC_SUBST(PY_ENABLE_SHARED) --LIBPL='$(prefix)'"/lib/python${VERSION}/config-${LDVERSION}" -+LIBPL='$(LIBDIR)'"/python${VERSION}/config-${LDVERSION}" - AC_SUBST(LIBPL) - - # Check whether right shifting a negative integer extends the sign bit --- -1.7.9.5 - diff --git a/meta/recipes-devtools/python/python3/create_manifest3.py b/meta/recipes-devtools/python/python3/create_manifest3.py new file mode 100644 index 0000000000..045240ea0b --- /dev/null +++ b/meta/recipes-devtools/python/python3/create_manifest3.py @@ -0,0 +1,444 @@ +# This script is used as a bitbake task to create a new python manifest +# $ bitbake python -c create_manifest +# +# Our goal is to keep python-core as small as posible and add other python +# packages only when the user needs them, hence why we split upstream python +# into several packages. +# +# In a very simplistic way what this does is: +# Launch python and see specifically what is required for it to run at a minimum +# +# Go through the python-manifest file and launch a separate task for every single +# one of the files on each package, this task will check what was required for that +# specific module to run, these modules will be called dependencies. +# The output of such task will be a list of the modules or dependencies that were +# found for that file. +# +# Such output will be parsed by this script, we will look for each dependency on the +# manifest and if we find that another package already includes it, then we will add +# that package as an RDEPENDS to the package we are currently checking; in case we dont +# find the current dependency on any other package we will add it to the current package +# as part of FILES. +# +# +# This way we will create a new manifest from the data structure that was built during +# this process, on this new manifest each package will contain specifically only +# what it needs to run. +# +# There are some caveats which we try to deal with, such as repeated files on different +# packages, packages that include folders, wildcards, and special packages. +# Its also important to note that this method only works for python files, and shared +# libraries. Static libraries, header files and binaries need to be dealt with manually. +# +# This script differs from its python2 version mostly on how shared libraries are handled +# The manifest file for python3 has an extra field which contains the cached files for +# each package. +# Tha method to handle cached files does not work when a module includes a folder which +# itself contains the pycache folder, gladly this is almost never the case. +# +# Author: Alejandro Enedino Hernandez Samaniego <alejandro at enedino dot org> + + +import sys +import subprocess +import json +import os +import collections + +if '-d' in sys.argv: + debugFlag = '-d' +else: + debugFlag = '' + +# Get python version from ${PYTHON_MAJMIN} +pyversion = str(sys.argv[1]) + +# Hack to get native python search path (for folders), not fond of it but it works for now +pivot = 'recipe-sysroot-native' +for p in sys.path: + if pivot in p: + nativelibfolder = p[:p.find(pivot)+len(pivot)] + +# Empty dict to hold the whole manifest +new_manifest = collections.OrderedDict() + +# Check for repeated files, folders and wildcards +allfiles = [] +repeated = [] +wildcards = [] + +hasfolders = [] +allfolders = [] + +def isFolder(value): + value = value.replace('${PYTHON_MAJMIN}',pyversion) + if os.path.isdir(value.replace('${libdir}',nativelibfolder+'/usr/lib')) or os.path.isdir(value.replace('${libdir}',nativelibfolder+'/usr/lib64')) or os.path.isdir(value.replace('${libdir}',nativelibfolder+'/usr/lib32')): + return True + else: + return False + +def isCached(item): + if '__pycache__' in item: + return True + else: + return False + +def prepend_comments(comments, json_manifest): + with open(json_manifest, 'r+') as manifest: + json_contents = manifest.read() + manifest.seek(0, 0) + manifest.write(comments + json_contents) + +def print_indent(msg, offset): + for l in msg.splitlines(): + msg = ' ' * offset + l + print(msg) + + +# Read existing JSON manifest +with open('python3-manifest.json') as manifest: + # The JSON format doesn't allow comments so we hack the call to keep the comments using a marker + manifest_str = manifest.read() + json_start = manifest_str.find('# EOC') + 6 # EOC + \n + manifest.seek(0) + comments = manifest.read(json_start) + manifest_str = manifest.read() + old_manifest = json.loads(manifest_str, object_pairs_hook=collections.OrderedDict) + +# +# First pass to get core-package functionality, because we base everything on the fact that core is actually working +# Not exactly the same so it should not be a function +# + +print_indent('Getting dependencies for package: core', 0) + + +# This special call gets the core dependencies and +# appends to the old manifest so it doesnt hurt what it +# currently holds. +# This way when other packages check for dependencies +# on the new core package, they will still find them +# even when checking the old_manifest + +output = subprocess.check_output([sys.executable, 'get_module_deps3.py', 'python-core-package', '%s' % debugFlag]).decode('utf8') +for coredep in output.split(): + coredep = coredep.replace(pyversion,'${PYTHON_MAJMIN}') + if isCached(coredep): + if coredep not in old_manifest['core']['cached']: + old_manifest['core']['cached'].append(coredep) + else: + if coredep not in old_manifest['core']['files']: + old_manifest['core']['files'].append(coredep) + + +# The second step is to loop through the existing files contained in the core package +# according to the old manifest, identify if they are modules, or some other type +# of file that we cant import (directories, binaries, configs) in which case we +# can only assume they were added correctly (manually) so we ignore those and +# pass them to the manifest directly. + +for filedep in old_manifest['core']['files']: + if isFolder(filedep): + if isCached(filedep): + if filedep not in old_manifest['core']['cached']: + old_manifest['core']['cached'].append(filedep) + else: + if filedep not in old_manifest['core']['files']: + old_manifest['core']['files'].append(filedep) + continue + if '${bindir}' in filedep: + if filedep not in old_manifest['core']['files']: + old_manifest['core']['files'].append(filedep) + continue + if filedep == '': + continue + if '${includedir}' in filedep: + if filedep not in old_manifest['core']['files']: + old_manifest['core']['files'].append(filedep) + continue + + # Get actual module name , shouldnt be affected by libdir/bindir, etc. + pymodule = os.path.splitext(os.path.basename(os.path.normpath(filedep)))[0] + + # We now know that were dealing with a python module, so we can import it + # and check what its dependencies are. + # We launch a separate task for each module for deterministic behavior. + # Each module will only import what is necessary for it to work in specific. + # The output of each task will contain each module's dependencies + + print_indent('Getting dependencies for module: %s' % pymodule, 2) + output = subprocess.check_output([sys.executable, 'get_module_deps3.py', '%s' % pymodule, '%s' % debugFlag]).decode('utf8') + print_indent('The following dependencies were found for module %s:\n' % pymodule, 4) + print_indent(output, 6) + + + for pymodule_dep in output.split(): + pymodule_dep = pymodule_dep.replace(pyversion,'${PYTHON_MAJMIN}') + + if isCached(pymodule_dep): + if pymodule_dep not in old_manifest['core']['cached']: + old_manifest['core']['cached'].append(pymodule_dep) + else: + if pymodule_dep not in old_manifest['core']['files']: + old_manifest['core']['files'].append(pymodule_dep) + + +# At this point we are done with the core package. +# The old_manifest dictionary is updated only for the core package because +# all others will use this a base. + + +print('\n\nChecking for directories...\n') +# To improve the script speed, we check which packages contain directories +# since we will be looping through (only) those later. +for pypkg in old_manifest: + for filedep in old_manifest[pypkg]['files']: + if isFolder(filedep): + print_indent('%s is a directory' % filedep, 2) + if pypkg not in hasfolders: + hasfolders.append(pypkg) + if filedep not in allfolders: + allfolders.append(filedep) + + + +# This is the main loop that will handle each package. +# It works in a similar fashion than the step before, but +# we will now be updating a new dictionary that will eventually +# become the new manifest. +# +# The following loops though all packages in the manifest, +# through all files on each of them, and checks whether or not +# they are modules and can be imported. +# If they can be imported, then it checks for dependencies for +# each of them by launching a separate task. +# The output of that task is then parsed and the manifest is updated +# accordingly, wether it should add the module on FILES for the current package +# or if that module already belongs to another package then the current one +# will RDEPEND on it + +for pypkg in old_manifest: + # Use an empty dict as data structure to hold data for each package and fill it up + new_manifest[pypkg] = collections.OrderedDict() + new_manifest[pypkg]['summary'] = old_manifest[pypkg]['summary'] + new_manifest[pypkg]['rdepends'] = [] + new_manifest[pypkg]['files'] = [] + new_manifest[pypkg]['cached'] = old_manifest[pypkg]['cached'] + + # All packages should depend on core + if pypkg != 'core': + new_manifest[pypkg]['rdepends'].append('core') + new_manifest[pypkg]['cached'] = [] + + print('\n') + print('--------------------------') + print('Handling package %s' % pypkg) + print('--------------------------') + + # Handle special cases, we assume that when they were manually added + # to the manifest we knew what we were doing. + special_packages = ['misc', 'modules', 'dev', 'tests'] + if pypkg in special_packages or 'staticdev' in pypkg: + print_indent('Passing %s package directly' % pypkg, 2) + new_manifest[pypkg] = old_manifest[pypkg] + continue + + for filedep in old_manifest[pypkg]['files']: + # We already handled core on the first pass, we can ignore it now + if pypkg == 'core': + if filedep not in new_manifest[pypkg]['files']: + new_manifest[pypkg]['files'].append(filedep) + continue + + # Handle/ignore what we cant import + if isFolder(filedep): + new_manifest[pypkg]['files'].append(filedep) + # Asyncio (and others) are both the package and the folder name, we should not skip those... + path,mod = os.path.split(filedep) + if mod != pypkg: + continue + if '${bindir}' in filedep: + if filedep not in new_manifest[pypkg]['files']: + new_manifest[pypkg]['files'].append(filedep) + continue + if filedep == '': + continue + if '${includedir}' in filedep: + if filedep not in new_manifest[pypkg]['files']: + new_manifest[pypkg]['files'].append(filedep) + continue + + # Get actual module name , shouldnt be affected by libdir/bindir, etc. + # We need to check if the imported module comes from another (e.g. sqlite3.dump) + path, pymodule = os.path.split(filedep) + path = os.path.basename(path) + pymodule = os.path.splitext(os.path.basename(pymodule))[0] + + # If this condition is met, it means we need to import it from another module + # or its the folder itself (e.g. unittest) + if path == pypkg: + if pymodule: + pymodule = path + '.' + pymodule + else: + pymodule = path + + + + # We now know that were dealing with a python module, so we can import it + # and check what its dependencies are. + # We launch a separate task for each module for deterministic behavior. + # Each module will only import what is necessary for it to work in specific. + # The output of each task will contain each module's dependencies + + print_indent('\nGetting dependencies for module: %s' % pymodule, 2) + output = subprocess.check_output([sys.executable, 'get_module_deps3.py', '%s' % pymodule, '%s' % debugFlag]).decode('utf8') + print_indent('The following dependencies were found for module %s:\n' % pymodule, 4) + print_indent(output, 6) + + reportFILES = [] + reportRDEPS = [] + + for pymodule_dep in output.split(): + + # Warning: This first part is ugly + # One of the dependencies that was found, could be inside of one of the folders included by another package + # We need to check if this happens so we can add the package containing the folder as an rdependency + # e.g. Folder encodings contained in codecs + # This would be solved if no packages included any folders + + # This can be done in two ways: + # 1 - We assume that if we take out the filename from the path we would get + # the folder string, then we would check if folder string is in the list of folders + # This would not work if a package contains a folder which contains another folder + # e.g. path/folder1/folder2/filename folder_string= path/folder1/folder2 + # folder_string would not match any value contained in the list of folders + # + # 2 - We do it the other way around, checking if the folder is contained in the path + # e.g. path/folder1/folder2/filename folder_string= path/folder1/folder2 + # is folder_string inside path/folder1/folder2/filename?, + # Yes, it works, but we waste a couple of milliseconds. + + pymodule_dep = pymodule_dep.replace(pyversion,'${PYTHON_MAJMIN}') + inFolders = False + for folder in allfolders: + # The module could have a directory named after it, e.g. xml, if we take out the filename from the path + # we'll end up with ${libdir}, and we want ${libdir}/xml + if isFolder(pymodule_dep): + check_path = pymodule_dep + else: + check_path = os.path.dirname(pymodule_dep) + if folder in check_path : + inFolders = True # Did we find a folder? + folderFound = False # Second flag to break inner for + # Loop only through packages which contain folders + for pypkg_with_folder in hasfolders: + if (folderFound == False): + # print('Checking folder %s on package %s' % (pymodule_dep,pypkg_with_folder)) + for folder_dep in old_manifest[pypkg_with_folder]['files'] or folder_dep in old_manifest[pypkg_with_folder]['cached']: + if folder_dep == folder: + print ('%s directory found in %s' % (folder, pypkg_with_folder)) + folderFound = True + if pypkg_with_folder not in new_manifest[pypkg]['rdepends'] and pypkg_with_folder != pypkg: + new_manifest[pypkg]['rdepends'].append(pypkg_with_folder) + else: + break + + # A folder was found so we're done with this item, we can go on + if inFolders: + continue + + + + # No directories beyond this point + # We might already have this module on the dictionary since it could depend on a (previously checked) module + if pymodule_dep not in new_manifest[pypkg]['files'] and pymodule_dep not in new_manifest[pypkg]['cached']: + # Handle core as a special package, we already did it so we pass it to NEW data structure directly + if pypkg == 'core': + print('Adding %s to %s FILES' % (pymodule_dep, pypkg)) + if pymodule_dep.endswith('*'): + wildcards.append(pymodule_dep) + if isCached(pymodule_dep): + new_manifest[pypkg]['cached'].append(pymodule_dep) + else: + new_manifest[pypkg]['files'].append(pymodule_dep) + + # Check for repeated files + if pymodule_dep not in allfiles: + allfiles.append(pymodule_dep) + else: + if pymodule_dep not in repeated: + repeated.append(pymodule_dep) + else: + + + # Last step: Figure out if we this belongs to FILES or RDEPENDS + # We check if this module is already contained on another package, so we add that one + # as an RDEPENDS, or if its not, it means it should be contained on the current + # package, and we should add it to FILES + for possible_rdep in old_manifest: + # Debug + # print('Checking %s ' % pymodule_dep + ' in %s' % possible_rdep) + if pymodule_dep in old_manifest[possible_rdep]['files'] or pymodule_dep in old_manifest[possible_rdep]['cached']: + # Since were nesting, we need to check its not the same pypkg + if(possible_rdep != pypkg): + if possible_rdep not in new_manifest[pypkg]['rdepends']: + # Add it to the new manifest data struct as RDEPENDS since it contains something this module needs + reportRDEPS.append('Adding %s to %s RDEPENDS, because it contains %s\n' % (possible_rdep, pypkg, pymodule_dep)) + new_manifest[pypkg]['rdepends'].append(possible_rdep) + break + else: + + # Since this module wasnt found on another package, it is not an RDEP, + # so we add it to FILES for this package. + # A module shouldn't contain itself (${libdir}/python3/sqlite3 shouldnt be on sqlite3 files) + if os.path.basename(pymodule_dep) != pypkg: + reportFILES.append(('Adding %s to %s FILES\n' % (pymodule_dep, pypkg))) + if isCached(pymodule_dep): + new_manifest[pypkg]['cached'].append(pymodule_dep) + else: + new_manifest[pypkg]['files'].append(pymodule_dep) + if pymodule_dep.endswith('*'): + wildcards.append(pymodule_dep) + if pymodule_dep not in allfiles: + allfiles.append(pymodule_dep) + else: + if pymodule_dep not in repeated: + repeated.append(pymodule_dep) + + print('\n') + print('#################################') + print('Summary for module %s' % pymodule) + print('FILES found for module %s:' % pymodule) + print(''.join(reportFILES)) + print('RDEPENDS found for module %s:' % pymodule) + print(''.join(reportRDEPS)) + print('#################################') + +print('The following FILES contain wildcards, please check if they are necessary') +print(wildcards) +print('The following FILES contain folders, please check if they are necessary') +print(hasfolders) + + +# Sort it just so it looks nicer +for pypkg in new_manifest: + new_manifest[pypkg]['files'].sort() + new_manifest[pypkg]['cached'].sort() + new_manifest[pypkg]['rdepends'].sort() + +# Create the manifest from the data structure that was built +with open('python3-manifest.json.new','w') as outfile: + json.dump(new_manifest,outfile, indent=4) + outfile.write('\n') + +prepend_comments(comments,'python3-manifest.json.new') + +if (repeated): + error_msg = '\n\nERROR:\n' + error_msg += 'The following files were found in more than one package),\n' + error_msg += 'this is likely to happen when new files are introduced after an upgrade,\n' + error_msg += 'please check which package should get it,\n modify the manifest accordingly and re-run the create_manifest task:\n' + error_msg += '\n'.join(repeated) + error_msg += '\n' + sys.exit(error_msg) + diff --git a/meta/recipes-devtools/python/python3/crosspythonpath.patch b/meta/recipes-devtools/python/python3/crosspythonpath.patch new file mode 100644 index 0000000000..2c4aef0511 --- /dev/null +++ b/meta/recipes-devtools/python/python3/crosspythonpath.patch @@ -0,0 +1,34 @@ +From 5b66463c10fec1440e977d5a21a0167862d6d79c Mon Sep 17 00:00:00 2001 +From: Ricardo Ribalda <ricardo@ribalda.com> +Date: Tue, 18 Nov 2014 03:35:33 -0500 +Subject: [PATCH] configure.ac: add CROSSPYTHONPATH into PYTHONPATH for + PYTHON_FOR_BUILD + +When building x86->x86 the system will try to execute .so and related items +from the default PYTHONPATH. This will fail if the target CPU contains +instructions that the host CPU does not have, add CROSSPYTHONPATH +into PYTHONPATH so we can prepend the list to find correct libs. + +Upstream-Status: Inappropriate [OE-Core integration specific] + +Credits-to: Mark Hatle <mark.hatle@windriver.com> +Credits-to: Jackie Huang <jackie.huang@windriver.com> +Signed-off-by: Ricardo Ribalda <ricardo@ribalda.com> + +--- + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/configure.ac b/configure.ac +index cb9e198..d81c19a 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -165,7 +165,7 @@ AC_ARG_WITH([build-python], + dnl Build Python interpreter is used for regeneration and freezing. + ac_cv_prog_PYTHON_FOR_REGEN=$with_build_python + PYTHON_FOR_FREEZE="$with_build_python" +- PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`:)$(srcdir)/Lib _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) '$with_build_python ++ PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(CROSSPYTHONPATH):$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`:)$(srcdir)/Lib _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) '$with_build_python + AC_MSG_RESULT([$with_build_python]) + ], [ + AS_VAR_IF([cross_compiling], [yes], diff --git a/meta/recipes-devtools/python/python3/deterministic_imports.patch b/meta/recipes-devtools/python/python3/deterministic_imports.patch new file mode 100644 index 0000000000..104df94964 --- /dev/null +++ b/meta/recipes-devtools/python/python3/deterministic_imports.patch @@ -0,0 +1,40 @@ +From 039d5e652796b55f1132afa568c7432b6ed89afd Mon Sep 17 00:00:00 2001 +From: Richard Purdie <richard.purdie@linuxfoundation.org> +Date: Fri, 27 May 2022 17:05:44 +0100 +Subject: [PATCH] python3: Ensure stale empty python module directories don't + +There are two issues here. Firstly, the modules are accessed in on disk order. This +means behaviour seen on one system might not reproduce on another and is a real headache. + +Secondly, empty directories left behind by previous modules might be looked at. This +has caused a long string of different issues for us. + +As a result, patch this to a behaviour which works for us. + +Upstream-Status: Pending [need to talk to upstream to see if they'll take one or both fixes] +Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> + +--- + Lib/importlib/metadata/__init__.py | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/Lib/importlib/metadata/__init__.py b/Lib/importlib/metadata/__init__.py +index 82e0ce1..969cac4 100644 +--- a/Lib/importlib/metadata/__init__.py ++++ b/Lib/importlib/metadata/__init__.py +@@ -710,7 +710,14 @@ class Lookup: + self.infos = FreezableDefaultDict(list) + self.eggs = FreezableDefaultDict(list) + +- for child in path.children(): ++ for child in sorted(path.children()): ++ childpath = pathlib.Path(path.root, child) ++ try: ++ if childpath.is_dir() and not any(childpath.iterdir()): ++ # Empty directories aren't interesting ++ continue ++ except PermissionError: ++ continue + low = child.lower() + if low.endswith((".dist-info", ".egg-info")): + # rpartition is faster than splitext and suitable for this purpose. diff --git a/meta/recipes-devtools/python/python3/fix_for_using_different_libdir.patch b/meta/recipes-devtools/python/python3/fix_for_using_different_libdir.patch deleted file mode 100644 index 0610565d3c..0000000000 --- a/meta/recipes-devtools/python/python3/fix_for_using_different_libdir.patch +++ /dev/null @@ -1,54 +0,0 @@ -Upstream-Status: Inappropriate [Embedded specific] - -This patch fixes issuing with different libdir like lib64. -This patch makes the native python binary modules findable -in the install process of the host python. - -Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com> -Date: 2012/03/14 - -Updated for python 2.7.3 -Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com> -Date: 2012/05/01 - -Index: Python-3.3.0rc2/Lib/sysconfig.py -=================================================================== ---- Python-3.3.0rc2.orig/Lib/sysconfig.py 2012-09-20 22:50:11.000000000 -0700 -+++ Python-3.3.0rc2/Lib/sysconfig.py 2012-09-20 22:53:01.561123396 -0700 -@@ -21,9 +21,9 @@ - - _INSTALL_SCHEMES = { - 'posix_prefix': { -- 'stdlib': '{installed_base}/'+sys.lib+'/python{py_version_short}', -+ 'stdlib': '{base}/'+sys.lib+'/python{py_version_short}', - 'platstdlib': '{platbase}/'+sys.lib+'/python{py_version_short}', -- 'purelib': '{base}/lib/python{py_version_short}/site-packages', -+ 'purelib': '{base}/'+sys.lib+'/python{py_version_short}/site-packages', - 'platlib': '{platbase}/'+sys.lib+'/python{py_version_short}/site-packages', - 'include': - '{installed_base}/include/python{py_version_short}{abiflags}', -@@ -83,7 +83,7 @@ - 'posix_user': { - 'stdlib': '{userbase}/'+sys.lib+'/python{py_version_short}', - 'platstdlib': '{userbase}/'+sys.lib+'/python{py_version_short}', -- 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', -+ 'purelib': '{userbase}/'+sys.lib+'/python{py_version_short}/site-packages', - 'platlib': '{userbase}/'+sys.lib+'/python{py_version_short}/site-packages', - 'include': '{userbase}/include/python{py_version_short}', - 'scripts': '{userbase}/bin', -Index: Python-3.3.0rc2/Makefile.pre.in -=================================================================== ---- Python-3.3.0rc2.orig/Makefile.pre.in 2012-09-20 22:50:11.000000000 -0700 -+++ Python-3.3.0rc2/Makefile.pre.in 2012-09-20 22:50:54.245123997 -0700 -@@ -1080,9 +1080,9 @@ - $(INSTALL_DATA) $(srcdir)/Modules/xxmodule.c \ - $(DESTDIR)$(LIBDEST)/distutils/tests ; \ - fi -- -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ -+ -PYTHONPATH=$(DESTDIR)$(LIBDEST):${CROSSPYTHONPATH} $(RUNSHARED) \ - $(PYTHON_FOR_BUILD) -m lib2to3.pgen2.driver $(DESTDIR)$(LIBDEST)/lib2to3/Grammar.txt -- -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ -+ -PYTHONPATH=$(DESTDIR)$(LIBDEST):${CROSSPYTHONPATH} $(RUNSHARED) \ - $(PYTHON_FOR_BUILD) -m lib2to3.pgen2.driver $(DESTDIR)$(LIBDEST)/lib2to3/PatternGrammar.txt - - # Create the PLATDIR source directory, if one wasn't distributed.. diff --git a/meta/recipes-devtools/python/python3/get_module_deps3.py b/meta/recipes-devtools/python/python3/get_module_deps3.py new file mode 100644 index 0000000000..8e432b49af --- /dev/null +++ b/meta/recipes-devtools/python/python3/get_module_deps3.py @@ -0,0 +1,174 @@ +# This script is launched on separate task for each python module +# It checks for dependencies for that specific module and prints +# them out, the output of this execution will have all dependencies +# for a specific module, which will be parsed an dealt on create_manifest.py +# +# Author: Alejandro Enedino Hernandez Samaniego <alejandro at enedino dot org> + + +import sys +import os + +# We can get a log per module, for all the dependencies that were found, but its messy. +if '-d' in sys.argv: + debug = True +else: + debug = False + +# We can get a list of the modules which are currently required to run python +# so we run python-core and get its modules, we then import what we need +# and check what modules are currently running, if we substract them from the +# modules we had initially, we get the dependencies for the module we imported. + +# We use importlib to achieve this, so we also need to know what modules importlib needs +import importlib + +core_deps = set(sys.modules) + +def fix_path(dep_path): + import os + # We DONT want the path on our HOST system + pivot = 'recipe-sysroot-native' + dep_path = dep_path[dep_path.find(pivot)+len(pivot):] + + if '/usr/bin' in dep_path: + dep_path = dep_path.replace('/usr/bin','${bindir}') + + # Handle multilib, is there a better way? + if '/usr/lib32' in dep_path: + dep_path = dep_path.replace('/usr/lib32','${libdir}') + if '/usr/lib64' in dep_path: + dep_path = dep_path.replace('/usr/lib64','${libdir}') + if '/usr/lib' in dep_path: + dep_path = dep_path.replace('/usr/lib','${libdir}') + if '/usr/include' in dep_path: + dep_path = dep_path.replace('/usr/include','${includedir}') + if '__init__.' in dep_path: + dep_path = os.path.split(dep_path)[0] + return dep_path + + +# Module to import was passed as an argument +current_module = str(sys.argv[1]).rstrip() +if debug == True: + log = open('temp/log_%s' % current_module.strip('.*'),'w') + log.write('Module %s generated the following dependencies:\n' % current_module) +try: + m = importlib.import_module(current_module) + # handle python packages which may not include all modules in the __init__ + if hasattr(m, '__file__') and os.path.basename(m.__file__) == "__init__.py": + modulepath = os.path.dirname(m.__file__) + for i in os.listdir(modulepath): + if i.startswith("_") or not(i.endswith(".py")): + continue + submodule = "{}.{}".format(current_module, i[:-3]) + try: + importlib.import_module(submodule) + except: + pass # ignore all import or other exceptions raised during import +except ImportError as e: + if debug == True: + log.write('Module was not found\n') + pass + + +# Get current module dependencies, dif will contain a list of specific deps for this module +module_deps = set(sys.modules) + +# We handle the core package (1st pass on create_manifest.py) as a special case +if current_module == 'python-core-package': + dif = core_deps +else: + # We know this is not the core package, so there must be a difference. + dif = module_deps-core_deps + + +# Check where each dependency came from +for item in dif: + # Main module returns script filename, __main matches mp_main__ as well + if 'main__' in item: + continue + + dep_path = '' + try: + if debug == True: + log.write('\nCalling: sys.modules[' + '%s' % item + '].__file__\n') + dep_path = sys.modules['%s' % item].__file__ + except AttributeError as e: + # Deals with thread (builtin module) not having __file__ attribute + if debug == True: + log.write(item + ' ') + log.write(str(e)) + log.write('\n') + pass + except NameError as e: + # Deals with NameError: name 'dep_path' is not defined + # because module is not found (wasn't compiled?), e.g. bddsm + if debug == True: + log.write(item+' ') + log.write(str(e)) + pass + + if dep_path == '': + continue + if debug == True: + log.write('Dependency path found:\n%s\n' % dep_path) + + # Site-customize is a special case since we (OpenEmbedded) put it there manually + if 'sitecustomize' in dep_path: + dep_path = '${libdir}/python${PYTHON_MAJMIN}/sitecustomize.py' + # Prints out result, which is what will be used by create_manifest + print (dep_path) + continue + + dep_path = fix_path(dep_path) + + import sysconfig + soabi = sysconfig.get_config_var('SOABI') + # Check if its a shared library and deconstruct it + if soabi in dep_path: + if debug == True: + log.write('Shared library found in %s\n' % dep_path) + dep_path = dep_path.replace(soabi,'*') + print (dep_path) + continue + if "_sysconfigdata" in dep_path: + dep_path = dep_path.replace(sysconfig._get_sysconfigdata_name(), "_sysconfigdata*") + + if debug == True: + log.write(dep_path+'\n') + # Prints out result, which is what will be used by create_manifest + print (dep_path) + + + cpython_tag = sys.implementation.cache_tag + cached = '' + # Theres no naive way to find *.pyc files on python3 + try: + if debug == True: + log.write('\nCalling: sys.modules[' + '%s' % item + '].__cached__\n') + cached = sys.modules['%s' % item].__cached__ + except AttributeError as e: + # Deals with thread (builtin module) not having __cached__ attribute + if debug == True: + log.write(item + ' ') + log.write(str(e)) + log.write('\n') + pass + except NameError as e: + # Deals with NameError: name 'cached' is not defined + if debug == True: + log.write(item+' ') + log.write(str(e)) + pass + if cached is not None: + if debug == True: + log.write(cached + '\n') + cached = fix_path(cached) + cached = cached.replace(cpython_tag,'*') + if "_sysconfigdata" in cached: + cached = cached.replace(sysconfig._get_sysconfigdata_name(), "_sysconfigdata*") + print (cached) + +if debug == True: + log.close() diff --git a/meta/recipes-devtools/python/python3/host_include_contamination.patch b/meta/recipes-devtools/python/python3/host_include_contamination.patch deleted file mode 100644 index ef2054d9a9..0000000000 --- a/meta/recipes-devtools/python/python3/host_include_contamination.patch +++ /dev/null @@ -1,28 +0,0 @@ -when building python for qemux86-64 on ubuntu 11.10/64bit -it gropes into host includes and then mixes them with cross -includes and as a result some modules fail to compile and link -one of the modules is python-elementtree which is then not -found during image creation - -Proble is that setup.py tries to add native includes that newer -ubuntu has introduced for multiarch support. But that should -only happen for native builds and not cross building python -so we add a check here. - -Signed-off-by: Khem Raj <raj.khem@gmail.com> -Upstream-Status: Pending - -Index: Python-3.3.0rc2/setup.py -=================================================================== ---- Python-3.3.0rc2.orig/setup.py 2012-09-20 21:54:50.000000000 -0700 -+++ Python-3.3.0rc2/setup.py 2012-09-20 21:57:35.029123858 -0700 -@@ -402,6 +402,9 @@ - - if not find_executable('dpkg-architecture'): - return -+ if cross_compiling: -+ return -+ - opt = '' - if cross_compiling: - opt = '-t' + sysconfig.get_config_var('HOST_GNU_TYPE') diff --git a/meta/recipes-devtools/python/python3/makerace.patch b/meta/recipes-devtools/python/python3/makerace.patch new file mode 100644 index 0000000000..c1b20703e6 --- /dev/null +++ b/meta/recipes-devtools/python/python3/makerace.patch @@ -0,0 +1,31 @@ +From 9f827c29adbe656af3c8fc963fdd8f47aec0c442 Mon Sep 17 00:00:00 2001 +From: Richard Purdie <richard.purdie@linuxfoundation.org> +Date: Tue, 13 Jul 2021 23:19:29 +0100 +Subject: [PATCH] python3: Fix make race + +libainstall installs python-config.py but the .pyc cache files are generated +by the libinstall target. This means some builds may not generate the pyc files +for python-config.py depending on the order things happen in. This means builds +are not always reproducible. + +Add a dependency to avoid the race. + +Upstream-Status: Pending +Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> +--- + Makefile.pre.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.pre.in b/Makefile.pre.in +index 381feb0..77bf09a 100644 +--- a/Makefile.pre.in ++++ b/Makefile.pre.in +@@ -2250,7 +2250,7 @@ COMPILEALL_OPTS=-j0 + TEST_MODULES=@TEST_MODULES@ + + .PHONY: libinstall +-libinstall: all $(srcdir)/Modules/xxmodule.c ++libinstall: all $(srcdir)/Modules/xxmodule.c libainstall + @for i in $(SCRIPTDIR) $(LIBDEST); \ + do \ + if test ! -d $(DESTDIR)$$i; then \ diff --git a/meta/recipes-devtools/python/python3/pass-missing-libraries-to-Extension-for-mul.patch b/meta/recipes-devtools/python/python3/pass-missing-libraries-to-Extension-for-mul.patch deleted file mode 100644 index 5c3af6b626..0000000000 --- a/meta/recipes-devtools/python/python3/pass-missing-libraries-to-Extension-for-mul.patch +++ /dev/null @@ -1,82 +0,0 @@ -From a784b70d47ba2104afbcfd805e2a66cdc2109ec5 Mon Sep 17 00:00:00 2001 -From: Hongxu Jia <hongxu.jia@windriver.com> -Date: Fri, 4 Aug 2017 11:16:14 +0800 -Subject: [PATCH] setup.py: pass missing libraries to Extension for multiprocessing module - -In the following commit: -... -commit e711cafab13efc9c1fe6c5cd75826401445eb585 -Author: Benjamin Peterson <benjamin@python.org> -Date: Wed Jun 11 16:44:04 2008 +0000 - - Merged revisions 64104,64117 via svnmerge from - svn+ssh://pythondev@svn.python.org/python/trunk -... -(see diff in setup.py) -It assigned libraries for multiprocessing module according -the host_platform, but not pass it to Extension. - -In glibc, the following commit caused two definition of -sem_getvalue are different. -https://sourceware.org/git/?p=glibc.git;a=commit;h=042e1521c794a945edc43b5bfa7e69ad70420524 -(see diff in nptl/sem_getvalue.c for detail) -`__new_sem_getvalue' is the latest sem_getvalue@@GLIBC_2.1 -and `__old_sem_getvalue' is to compat the old version -sem_getvalue@GLIBC_2.0. - -To build python for embedded Linux systems: -http://www.yoctoproject.org/docs/2.3.1/yocto-project-qs/yocto-project-qs.html -If not explicitly link to library pthread (-lpthread), it will -load glibc's sem_getvalue randomly at runtime. - -Such as build python on linux x86_64 host and run the python -on linux x86_32 target. If not link library pthread, it caused -multiprocessing bounded semaphore could not work correctly. -... ->>> import multiprocessing ->>> pool_sema = multiprocessing.BoundedSemaphore(value=1) ->>> pool_sema.acquire() -True ->>> pool_sema.release() -Traceback (most recent call last): - File "<stdin>", line 1, in <module> -ValueError: semaphore or lock released too many times -... - -And the semaphore issue also caused multiprocessing.Queue().put() hung. - -Upstream-Status: Submitted [https://github.com/python/cpython/pull/2999] - -Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> ---- - setup.py | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/setup.py b/setup.py -index 4f0f522..d05707d 100644 ---- a/setup.py -+++ b/setup.py -@@ -1606,8 +1606,10 @@ class PyBuildExt(build_ext): - elif host_platform.startswith('netbsd'): - macros = dict() - libraries = [] -- -- else: # Linux and other unices -+ elif host_platform.startswith(('linux')): -+ macros = dict() -+ libraries = ['pthread'] -+ else: # Other unices - macros = dict() - libraries = ['rt'] - -@@ -1626,6 +1628,7 @@ class PyBuildExt(build_ext): - if sysconfig.get_config_var('WITH_THREAD'): - exts.append ( Extension('_multiprocessing', multiprocessing_srcs, - define_macros=list(macros.items()), -+ libraries=libraries, - include_dirs=["Modules/_multiprocessing"])) - else: - missing.append('_multiprocessing') --- -2.7.4 - diff --git a/meta/recipes-devtools/python/python3/python-3.3-multilib.patch b/meta/recipes-devtools/python/python3/python-3.3-multilib.patch deleted file mode 100644 index 08c4403cbf..0000000000 --- a/meta/recipes-devtools/python/python3/python-3.3-multilib.patch +++ /dev/null @@ -1,361 +0,0 @@ -From 51fe6f22d0ba113674fb358bd11d75fe659bd26e Mon Sep 17 00:00:00 2001 -From: Khem Raj <raj.khem@gmail.com> -Date: Tue, 14 May 2013 15:00:26 -0700 -Subject: [PATCH 01/13] get the sys.lib from python itself and do not use - hardcoded value of 'lib' - -02/2015 Rebased for 3.4.2 - -Upstream-Status: Pending -Signed-off-by: Khem Raj <raj.khem@gmail.com> -Signed-off-by: Alejandro Hernandez <alejandro.hernandez@linux.intel.com> - ---- - Include/pythonrun.h | 3 +++ - Lib/distutils/command/install.py | 4 +++- - Lib/pydoc.py | 2 +- - Lib/site.py | 4 ++-- - Lib/sysconfig.py | 18 +++++++++--------- - Lib/trace.py | 4 ++-- - Makefile.pre.in | 7 +++++-- - Modules/getpath.c | 10 +++++++++- - Python/getplatform.c | 20 ++++++++++++++++++++ - Python/sysmodule.c | 4 ++++ - configure.ac | 35 +++++++++++++++++++++++++++++++++++ - setup.py | 9 ++++----- - 12 files changed, 97 insertions(+), 23 deletions(-) - -diff --git a/Include/pythonrun.h b/Include/pythonrun.h -index 9c2e813..2f79cb6 100644 ---- a/Include/pythonrun.h -+++ b/Include/pythonrun.h -@@ -23,6 +23,9 @@ typedef struct { - } PyCompilerFlags; - #endif - -+PyAPI_FUNC(const char *) Py_GetArch(void); -+PyAPI_FUNC(const char *) Py_GetLib(void); -+ - #ifndef Py_LIMITED_API - PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *); - PyAPI_FUNC(int) PyRun_AnyFileFlags(FILE *, const char *, PyCompilerFlags *); -diff --git a/Lib/distutils/command/install.py b/Lib/distutils/command/install.py -index 67db007..b46b45b 100644 ---- a/Lib/distutils/command/install.py -+++ b/Lib/distutils/command/install.py -@@ -19,6 +19,8 @@ from site import USER_BASE - from site import USER_SITE - HAS_USER_SITE = True - -+libname = sys.lib -+ - WINDOWS_SCHEME = { - 'purelib': '$base/Lib/site-packages', - 'platlib': '$base/Lib/site-packages', -@@ -30,7 +32,7 @@ WINDOWS_SCHEME = { - INSTALL_SCHEMES = { - 'unix_prefix': { - 'purelib': '$base/lib/python$py_version_short/site-packages', -- 'platlib': '$platbase/lib/python$py_version_short/site-packages', -+ 'platlib': '$platbase/'+libname+'/python$py_version_short/site-packages', - 'headers': '$base/include/python$py_version_short$abiflags/$dist_name', - 'scripts': '$base/bin', - 'data' : '$base', -diff --git a/Lib/pydoc.py b/Lib/pydoc.py -index 3ca08c9..6528730 100755 ---- a/Lib/pydoc.py -+++ b/Lib/pydoc.py -@@ -384,7 +384,7 @@ class Doc: - docmodule = docclass = docroutine = docother = docproperty = docdata = fail - - def getdocloc(self, object, -- basedir=os.path.join(sys.base_exec_prefix, "lib", -+ basedir=os.path.join(sys.base_exec_prefix, sys.lib, - "python%d.%d" % sys.version_info[:2])): - """Return the location of module docs or None""" - -diff --git a/Lib/site.py b/Lib/site.py -index 3f78ef5..511931e 100644 ---- a/Lib/site.py -+++ b/Lib/site.py -@@ -303,12 +303,12 @@ def getsitepackages(prefixes=None): - seen.add(prefix) - - if os.sep == '/': -- sitepackages.append(os.path.join(prefix, "lib", -+ sitepackages.append(os.path.join(prefix, sys.lib, - "python" + sys.version[:3], - "site-packages")) - else: - sitepackages.append(prefix) -- sitepackages.append(os.path.join(prefix, "lib", "site-packages")) -+ sitepackages.append(os.path.join(prefix, sys.lib, "site-packages")) - if sys.platform == "darwin": - # for framework builds *only* we add the standard Apple - # locations. -diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py -index 9c34be0..3d1181a 100644 ---- a/Lib/sysconfig.py -+++ b/Lib/sysconfig.py -@@ -20,10 +20,10 @@ __all__ = [ - - _INSTALL_SCHEMES = { - 'posix_prefix': { -- 'stdlib': '{installed_base}/lib/python{py_version_short}', -- 'platstdlib': '{platbase}/lib/python{py_version_short}', -+ 'stdlib': '{installed_base}/'+sys.lib+'/python{py_version_short}', -+ 'platstdlib': '{platbase}/'+sys.lib+'/python{py_version_short}', - 'purelib': '{base}/lib/python{py_version_short}/site-packages', -- 'platlib': '{platbase}/lib/python{py_version_short}/site-packages', -+ 'platlib': '{platbase}/'+sys.lib+'/python{py_version_short}/site-packages', - 'include': - '{installed_base}/include/python{py_version_short}{abiflags}', - 'platinclude': -@@ -32,10 +32,10 @@ _INSTALL_SCHEMES = { - 'data': '{base}', - }, - 'posix_home': { -- 'stdlib': '{installed_base}/lib/python', -- 'platstdlib': '{base}/lib/python', -+ 'stdlib': '{installed_base}/'+sys.lib+'/python', -+ 'platstdlib': '{base}/'+sys.lib+'/python', - 'purelib': '{base}/lib/python', -- 'platlib': '{base}/lib/python', -+ 'platlib': '{base}/'+sys.lib+'/python', - 'include': '{installed_base}/include/python', - 'platinclude': '{installed_base}/include/python', - 'scripts': '{base}/bin', -@@ -61,10 +61,10 @@ _INSTALL_SCHEMES = { - 'data': '{userbase}', - }, - 'posix_user': { -- 'stdlib': '{userbase}/lib/python{py_version_short}', -- 'platstdlib': '{userbase}/lib/python{py_version_short}', -+ 'stdlib': '{userbase}/'+sys.lib+'/python{py_version_short}', -+ 'platstdlib': '{userbase}/'+sys.lib+'/python{py_version_short}', - 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', -- 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', -+ 'platlib': '{userbase}/'+sys.lib+'/python{py_version_short}/site-packages', - 'include': '{userbase}/include/python{py_version_short}', - 'scripts': '{userbase}/bin', - 'data': '{userbase}', -diff --git a/Lib/trace.py b/Lib/trace.py -index f108266..7fd83f2 100755 ---- a/Lib/trace.py -+++ b/Lib/trace.py -@@ -749,10 +749,10 @@ def main(argv=None): - # should I also call expanduser? (after all, could use $HOME) - - s = s.replace("$prefix", -- os.path.join(sys.base_prefix, "lib", -+ os.path.join(sys.base_prefix, sys.lib, - "python" + sys.version[:3])) - s = s.replace("$exec_prefix", -- os.path.join(sys.base_exec_prefix, "lib", -+ os.path.join(sys.base_exec_prefix, sys.lib, - "python" + sys.version[:3])) - s = os.path.normpath(s) - ignore_dirs.append(s) -diff --git a/Makefile.pre.in b/Makefile.pre.in -index 109f402..61a41e2 100644 ---- a/Makefile.pre.in -+++ b/Makefile.pre.in -@@ -106,6 +106,8 @@ PY_CORE_CFLAGS= $(PY_CFLAGS) $(PY_CFLAGS_NODIST) $(PY_CPPFLAGS) $(CFLAGSFORSHARE - - # Machine-dependent subdirectories - MACHDEP= @MACHDEP@ -+LIB= @LIB@ -+ARCH= @ARCH@ - - # Multiarch directory (may be empty) - MULTIARCH= @MULTIARCH@ -@@ -125,7 +127,7 @@ LIBDIR= @libdir@ - MANDIR= @mandir@ - INCLUDEDIR= @includedir@ - CONFINCLUDEDIR= $(exec_prefix)/include --SCRIPTDIR= $(prefix)/lib -+SCRIPTDIR= @libdir@ - ABIFLAGS= @ABIFLAGS@ - - # Detailed destination directories -@@ -755,6 +757,7 @@ Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile - -DEXEC_PREFIX='"$(exec_prefix)"' \ - -DVERSION='"$(VERSION)"' \ - -DVPATH='"$(VPATH)"' \ -+ -DARCH='"$(ARCH)"' -DLIB='"$(LIB)"' \ - -o $@ $(srcdir)/Modules/getpath.c - - Programs/python.o: $(srcdir)/Programs/python.c -@@ -835,7 +838,7 @@ $(OPCODE_H): $(srcdir)/Lib/opcode.py $(OPCODE_H_SCRIPT) - Python/compile.o Python/symtable.o Python/ast.o: $(GRAMMAR_H) $(AST_H) - - Python/getplatform.o: $(srcdir)/Python/getplatform.c -- $(CC) -c $(PY_CORE_CFLAGS) -DPLATFORM='"$(MACHDEP)"' -o $@ $(srcdir)/Python/getplatform.c -+ $(CC) -c $(PY_CORE_CFLAGS) -DPLATFORM='"$(MACHDEP)"' -DARCH='"$(ARCH)"' -DLIB='"$(LIB)"' -o $@ $(srcdir)/Python/getplatform.c - - Python/importdl.o: $(srcdir)/Python/importdl.c - $(CC) -c $(PY_CORE_CFLAGS) -I$(DLINCLDIR) -o $@ $(srcdir)/Python/importdl.c -diff --git a/Modules/getpath.c b/Modules/getpath.c -index 18deb60..a01c3f8 100644 ---- a/Modules/getpath.c -+++ b/Modules/getpath.c -@@ -105,6 +105,13 @@ - #error "PREFIX, EXEC_PREFIX, VERSION, and VPATH must be constant defined" - #endif - -+#define LIB_PYTHON LIB "/python" VERSION -+ -+#ifndef PYTHONPATH -+#define PYTHONPATH PREFIX "/" LIB_PYTHON ":" \ -+ EXEC_PREFIX "/" LIB_PYTHON "/lib-dynload" -+#endif -+ - #ifndef LANDMARK - #define LANDMARK L"os.py" - #endif -@@ -113,6 +120,7 @@ static wchar_t prefix[MAXPATHLEN+1]; - static wchar_t exec_prefix[MAXPATHLEN+1]; - static wchar_t progpath[MAXPATHLEN+1]; - static wchar_t *module_search_path = NULL; -+static wchar_t *lib_python = L"" LIB_PYTHON; - - /* Get file status. Encode the path to the locale encoding. */ - -@@ -494,7 +502,7 @@ calculate_path(void) - _pythonpath = Py_DecodeLocale(PYTHONPATH, NULL); - _prefix = Py_DecodeLocale(PREFIX, NULL); - _exec_prefix = Py_DecodeLocale(EXEC_PREFIX, NULL); -- lib_python = Py_DecodeLocale("lib/python" VERSION, NULL); -+ lib_python = Py_DecodeLocale(LIB_PYTHON, NULL); - - if (!_pythonpath || !_prefix || !_exec_prefix || !lib_python) { - Py_FatalError( -diff --git a/Python/getplatform.c b/Python/getplatform.c -index 6899140..66a49c6 100644 ---- a/Python/getplatform.c -+++ b/Python/getplatform.c -@@ -10,3 +10,23 @@ Py_GetPlatform(void) - { - return PLATFORM; - } -+ -+#ifndef ARCH -+#define ARCH "unknown" -+#endif -+ -+const char * -+Py_GetArch(void) -+{ -+ return ARCH; -+} -+ -+#ifndef LIB -+#define LIB "lib" -+#endif -+ -+const char * -+Py_GetLib(void) -+{ -+ return LIB; -+} -diff --git a/Python/sysmodule.c b/Python/sysmodule.c -index 8d7e05a..d9dee0f 100644 ---- a/Python/sysmodule.c -+++ b/Python/sysmodule.c -@@ -1790,6 +1790,10 @@ _PySys_Init(void) - PyUnicode_FromString(Py_GetCopyright())); - SET_SYS_FROM_STRING("platform", - PyUnicode_FromString(Py_GetPlatform())); -+ SET_SYS_FROM_STRING("arch", -+ PyUnicode_FromString(Py_GetArch())); -+ SET_SYS_FROM_STRING("lib", -+ PyUnicode_FromString(Py_GetLib())); - SET_SYS_FROM_STRING("executable", - PyUnicode_FromWideChar( - Py_GetProgramFullPath(), -1)); -diff --git a/configure.ac b/configure.ac -index 707324d..e8d59a3 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -883,6 +883,41 @@ PLATDIR=plat-$MACHDEP - AC_SUBST(PLATDIR) - AC_SUBST(PLATFORM_TRIPLET) - -+AC_SUBST(ARCH) -+AC_MSG_CHECKING(ARCH) -+ARCH=`uname -m` -+case $ARCH in -+i?86) ARCH=i386;; -+esac -+AC_MSG_RESULT($ARCH) -+ -+AC_SUBST(LIB) -+AC_MSG_CHECKING(LIB) -+case $ac_sys_system in -+Linux*) -+ # Test if the compiler is 64bit -+ echo 'int i;' > conftest.$ac_ext -+ python_cv_cc_64bit_output=no -+ if AC_TRY_EVAL(ac_compile); then -+ case `/usr/bin/file conftest.$ac_objext` in -+ *"ELF 64"*) -+ python_cv_cc_64bit_output=yes -+ ;; -+ esac -+ fi -+ rm -rf conftest* -+ ;; -+esac -+ -+case $ARCH:$python_cv_cc_64bit_output in -+ppc64:yes | powerpc64:yes | s390x:yes | sparc64:yes | x86_64:yes) -+ LIB="lib64" -+ ;; -+*:*) -+ LIB="lib" -+ ;; -+esac -+AC_MSG_RESULT($LIB) - - AC_MSG_CHECKING([for -Wl,--no-as-needed]) - save_LDFLAGS="$LDFLAGS" -diff --git a/setup.py b/setup.py -index 6d26deb..7b14215 100644 ---- a/setup.py -+++ b/setup.py -@@ -495,7 +495,7 @@ class PyBuildExt(build_ext): - # directories (i.e. '.' and 'Include') must be first. See issue - # 10520. - if not cross_compiling: -- add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib') -+ add_dir_to_list(self.compiler.library_dirs, os.path.join('/usr/local', sys.lib)) - add_dir_to_list(self.compiler.include_dirs, '/usr/local/include') - # only change this for cross builds for 3.3, issues on Mageia - if cross_compiling: -@@ -553,8 +553,7 @@ class PyBuildExt(build_ext): - # be assumed that no additional -I,-L directives are needed. - if not cross_compiling: - lib_dirs = self.compiler.library_dirs + [ -- '/lib64', '/usr/lib64', -- '/lib', '/usr/lib', -+ '/' + sys.lib, '/usr/' + sys.lib, - ] - inc_dirs = self.compiler.include_dirs + ['/usr/include'] - else: -@@ -746,11 +745,11 @@ class PyBuildExt(build_ext): - elif curses_library: - readline_libs.append(curses_library) - elif self.compiler.find_library_file(lib_dirs + -- ['/usr/lib/termcap'], -+ ['/usr/'+sys.lib+'/termcap'], - 'termcap'): - readline_libs.append('termcap') - exts.append( Extension('readline', ['readline.c'], -- library_dirs=['/usr/lib/termcap'], -+ library_dirs=['/usr/'+sys.lib+'/termcap'], - extra_link_args=readline_extra_link_args, - libraries=readline_libs) ) - else: --- -2.11.0 - diff --git a/meta/recipes-devtools/python/python3/python-config.patch b/meta/recipes-devtools/python/python3/python-config.patch deleted file mode 100644 index f23b8b7df0..0000000000 --- a/meta/recipes-devtools/python/python3/python-config.patch +++ /dev/null @@ -1,46 +0,0 @@ -python-config: Revert to using distutils.sysconfig - -The newer sysconfig module shares some code with distutils.sysconfig, but the same modifications as in - -12-distutils-prefix-is-inside-staging-area.patch makes distutils.sysconfig - -affect the native runtime as well as cross building. Use the old, patched -implementation which returns paths in the staging directory and for the target, -as appropriate. - -Upstream-Status: Inappropriate [Embedded Specific] - -Signed-off-by: Tyler Hall <tylerwhall@gmail.com> -: -Index: Python-3.3.3/Misc/python-config.in -=================================================================== ---- Python-3.3.3.orig/Misc/python-config.in -+++ Python-3.3.3/Misc/python-config.in -@@ -4,7 +4,7 @@ - import getopt - import os - import sys --import sysconfig -+from distutils import sysconfig - - valid_opts = ['prefix', 'exec-prefix', 'includes', 'libs', 'cflags', - 'ldflags', 'extension-suffix', 'help', 'abiflags', 'configdir'] -@@ -32,14 +32,14 @@ if '--help' in opt_flags: - - for opt in opt_flags: - if opt == '--prefix': -- print(sysconfig.get_config_var('prefix')) -+ print(sysconfig.PREFIX) - - elif opt == '--exec-prefix': -- print(sysconfig.get_config_var('exec_prefix')) -+ print(sysconfig.EXEC_PREFIX) - - elif opt in ('--includes', '--cflags'): -- flags = ['-I' + sysconfig.get_path('include'), -- '-I' + sysconfig.get_path('platinclude')] -+ flags = ['-I' + sysconfig.get_python_inc(), -+ '-I' + sysconfig.get_python_inc(plat_specific=True)] - if opt == '--cflags': - flags.extend(getvar('CFLAGS').split()) - print(' '.join(flags)) diff --git a/meta/recipes-devtools/python/python3/python3-manifest.json b/meta/recipes-devtools/python/python3/python3-manifest.json new file mode 100644 index 0000000000..46092d4004 --- /dev/null +++ b/meta/recipes-devtools/python/python3/python3-manifest.json @@ -0,0 +1,1286 @@ +# DO NOT (entirely) modify this file manually, please read. +# +# IMPORTANT NOTE: +# Please keep in mind that the create_manifest task relies on the fact the the +# target and native Python packages are the same, and it also needs to be executed +# with a fully working native package (with all the PACKAGECONFIGs enabled and all +# and all the modules should be working, check log.do_compile), otherwise the script +# will fail to find dependencies correctly, this note is valid either if you are +# upgrading to a new Python version or adding a new package. +# +# +# If you are adding a new package please follow the next steps: +# How to add a new package: +# - If a user wants to add a new package all that has to be done is: +# Modify the python3-manifest.json file, and add the required file(s) to the FILES list, +# fill up the SUMMARY section as well, the script should handle all the rest. +# +# Real example: +# We want to add a web browser package, including the file webbrowser.py +# which at the moment is on python3-misc. +# "webbrowser": { +# "files": ["${libdir}/python${PYTHON_MAJMIN}/lib-dynload/webbrowser.py"], +# "rdepends": [], +# "summary": "Python Web Browser support"} +# +# * Note that the rdepends field was left empty +# +# We run $ bitbake python3 -c create_manifest and the resulting manifest +# should be completed after a few seconds, showing something like: +# "webbrowser": { +# "files": ["${libdir}/python${PYTHON_MAJMIN}/webbrowser.py"], +# "rdepends": ["core","fcntl","io","pickle","shell","subprocess"], +# "summary": "Python Web Browser support"} +# +# +# If you are upgrading Python to a new version please follow the next steps: +# After each Python upgrade, the create_manifest task should be executed, because we +# don't control what changes on upstream Python, so, some module dependency +# might have changed without us realizing it, a certain module can either have +# more or less dependencies, or could be depending on a new file that was just +# created on the new release and for obvious reasons we wouldn't have it on our +# old manifest, all of these issues would cause runtime errors on our system. +# +# - Upgrade both the native and target Python packages to a new version +# - Run the create_manifest task for the target Python package as its shown below: +# +# $ bitbake python3 -c create_manifest +# +# This will automatically replace your manifest file located under the Python directory +# with an new one, which contains the new dependencies (if any). +# +# Several things could have gone wrong here, I will try to explain a few: +# +# a) A new file was introduced on this release, e.g. sha3*.so: +# The task will check what its needed to import every module, more than one module would +# would probably depend on sha3*.so, although only one module should contain it. +# +# After running the task, the new manifest will have the sha3*.so file on more than one +# module, you need to manually decide which one of them should get it and delete it from +# the others, for example sha3*.so should likely be on ${PN}-crypt. +# Once you have deleted from the others you need to run the create_manifest task again, +# this will populate the other module's rdepends fields, with ${PN}-crypt and you should be +# good to go. +# +# b) The native package wasn't built correctly and its missing a certain module: +# As mentioned before, you need to make sure the native package was built with all the modules +# because it is used as base to build the manifest file, you need to manually check log.do_compile +# since it won't error out the compile function if its only missing a couple of modules. +# +# e.g. missing the _uuid module, log.do_compile would show the following: +# Python build finished successfully! +# The necessary bits to build these optional modules were not found: +# _uuid +# +# What will happen here is that the new manifest would not be aware that the _uuid module exists, so +# not only we won't know of any dependencies to it, but also, the _uuid* files will be packaged on +# the misc package (which is where any file that doesn't belong anywhere else ends up). +# +# This will eventually cause runtime errors on our system if we don't include the misc package on +# on our image, because the _uuid files will be missing. +# If we build the _uuid module correctly and run the create_manifest task the _uuid files will be +# detected correctly along with its dependencies, and we will get a working manifest. +# +# This is the reason why it is important to make sure we have a fully working native build, +# so we can avoid these errors. +# +# +# +# DO NOT MODIFY THE NEXT LINE!, IT IS USED AS A MARKER FOR THE ACTUAL JSON MANIFEST +# EOC +{ + "tests": { + "summary": "Python test suite", + "rdepends": [ + "core", + "modules" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/*/test", + "${libdir}/python${PYTHON_MAJMIN}/*/tests", + "${libdir}/python${PYTHON_MAJMIN}/idlelib/idle_test/", + "${libdir}/python${PYTHON_MAJMIN}/test" + ], + "cached": [] + }, + "2to3": { + "summary": "Python automated Python 2 to 3 code translator", + "rdepends": [ + "core" + ], + "files": [ + "${bindir}/2to3*", + "${libdir}/python${PYTHON_MAJMIN}/lib2to3" + ], + "cached": [] + }, + "asyncio": { + "summary": "Python Asynchronous I/O", + "rdepends": [ + "core", + "io", + "logging", + "netclient", + "numbers", + "stringold" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/asyncio", + "${libdir}/python${PYTHON_MAJMIN}/concurrent", + "${libdir}/python${PYTHON_MAJMIN}/concurrent/futures", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_asyncio.*.so" + ], + "cached": [] + }, + "audio": { + "summary": "Python Audio Handling", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/chunk.py", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/audioop.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/ossaudiodev.*.so", + "${libdir}/python${PYTHON_MAJMIN}/sndhdr.py", + "${libdir}/python${PYTHON_MAJMIN}/sunau.py", + "${libdir}/python${PYTHON_MAJMIN}/wave.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/chunk.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/sndhdr.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/sunau.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/wave.*.pyc" + ] + }, + "cgitb": { + "summary": "Special exception handler for Python scripts", + "rdepends": [ + "core", + "crypt", + "html", + "io", + "math", + "pydoc" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/cgitb.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/cgitb.*.pyc" + ] + }, + "codecs": { + "summary": "Python codec", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_multibytecodec.*.so", + "${libdir}/python${PYTHON_MAJMIN}/xdrlib.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/xdrlib.*.pyc" + ] + }, + "compile": { + "summary": "Python bytecode compilation support", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/compileall.py", + "${libdir}/python${PYTHON_MAJMIN}/filecmp.py", + "${libdir}/python${PYTHON_MAJMIN}/py_compile.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/compileall.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/filecmp.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/py_compile.*.pyc" + ] + }, + "compression": { + "summary": "Python high-level compression support", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/gzip.py", + "${libdir}/python${PYTHON_MAJMIN}/tarfile.py", + "${libdir}/python${PYTHON_MAJMIN}/zipfile", + "${libdir}/python${PYTHON_MAJMIN}/zipfile/_path" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/gzip.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/tarfile.*.pyc" + ] + }, + "core": { + "summary": "Python interpreter and core modules", + "rdepends": [], + "files": [ + "${bindir}/python${PYTHON_MAJMIN}", + "${bindir}/python${PYTHON_MAJMIN}.real", + "${bindir}/python3", + "${includedir}/python${PYTHON_MAJMIN}/pyconfig*.h", + "${libdir}/python${PYTHON_MAJMIN}/UserDict.py", + "${libdir}/python${PYTHON_MAJMIN}/UserList.py", + "${libdir}/python${PYTHON_MAJMIN}/UserString.py", + "${libdir}/python${PYTHON_MAJMIN}/__future__.py", + "${libdir}/python${PYTHON_MAJMIN}/_abcoll.py", + "${libdir}/python${PYTHON_MAJMIN}/_bootlocale.py", + "${libdir}/python${PYTHON_MAJMIN}/_collections_abc.py", + "${libdir}/python${PYTHON_MAJMIN}/_compression.py", + "${libdir}/python${PYTHON_MAJMIN}/_markupbase.py", + "${libdir}/python${PYTHON_MAJMIN}/_sitebuiltins.py", + "${libdir}/python${PYTHON_MAJMIN}/_sysconfigdata*.py", + "${libdir}/python${PYTHON_MAJMIN}/_weakrefset.py", + "${libdir}/python${PYTHON_MAJMIN}/abc.py", + "${libdir}/python${PYTHON_MAJMIN}/argparse.py", + "${libdir}/python${PYTHON_MAJMIN}/ast.py", + "${libdir}/python${PYTHON_MAJMIN}/bisect.py", + "${libdir}/python${PYTHON_MAJMIN}/bz2.py", + "${libdir}/python${PYTHON_MAJMIN}/code.py", + "${libdir}/python${PYTHON_MAJMIN}/codecs.py", + "${libdir}/python${PYTHON_MAJMIN}/codeop.py", + "${libdir}/python${PYTHON_MAJMIN}/collections", + "${libdir}/python${PYTHON_MAJMIN}/collections/abc.py", + "${libdir}/python${PYTHON_MAJMIN}/configparser.py", + "${libdir}/python${PYTHON_MAJMIN}/contextlib.py", + "${libdir}/python${PYTHON_MAJMIN}/copy.py", + "${libdir}/python${PYTHON_MAJMIN}/copyreg.py", + "${libdir}/python${PYTHON_MAJMIN}/csv.py", + "${libdir}/python${PYTHON_MAJMIN}/dataclasses.py", + "${libdir}/python${PYTHON_MAJMIN}/dis.py", + "${libdir}/python${PYTHON_MAJMIN}/encodings", + "${libdir}/python${PYTHON_MAJMIN}/encodings/aliases.py", + "${libdir}/python${PYTHON_MAJMIN}/encodings/latin_1.py", + "${libdir}/python${PYTHON_MAJMIN}/encodings/utf_8.py", + "${libdir}/python${PYTHON_MAJMIN}/enum.py", + "${libdir}/python${PYTHON_MAJMIN}/fnmatch.py", + "${libdir}/python${PYTHON_MAJMIN}/functools.py", + "${libdir}/python${PYTHON_MAJMIN}/genericpath.py", + "${libdir}/python${PYTHON_MAJMIN}/getopt.py", + "${libdir}/python${PYTHON_MAJMIN}/gettext.py", + "${libdir}/python${PYTHON_MAJMIN}/heapq.py", + "${libdir}/python${PYTHON_MAJMIN}/imp.py", + "${libdir}/python${PYTHON_MAJMIN}/importlib", + "${libdir}/python${PYTHON_MAJMIN}/importlib/_abc.py", + "${libdir}/python${PYTHON_MAJMIN}/importlib/_bootstrap.py", + "${libdir}/python${PYTHON_MAJMIN}/importlib/_bootstrap_external.py", + "${libdir}/python${PYTHON_MAJMIN}/importlib/abc.py", + "${libdir}/python${PYTHON_MAJMIN}/importlib/machinery.py", + "${libdir}/python${PYTHON_MAJMIN}/importlib/util.py", + "${libdir}/python${PYTHON_MAJMIN}/inspect.py", + "${libdir}/python${PYTHON_MAJMIN}/io.py", + "${libdir}/python${PYTHON_MAJMIN}/ipaddress.py", + "${libdir}/python${PYTHON_MAJMIN}/keyword.py", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/__pycache__/_struct.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/__pycache__/binascii.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/__pycache__/time.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/__pycache__/xreadlines.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_bisect.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_bz2.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_csv.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_heapq.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_lzma.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_opcode.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_posixsubprocess.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_struct.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_typing.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/array.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/binascii.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/grp.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/math.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/parser.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/readline.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/select.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/time.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/unicodedata.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/xreadlines.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/zlib.*.so", + "${libdir}/python${PYTHON_MAJMIN}/linecache.py", + "${libdir}/python${PYTHON_MAJMIN}/locale.py", + "${libdir}/python${PYTHON_MAJMIN}/lzma.py", + "${libdir}/python${PYTHON_MAJMIN}/new.py", + "${libdir}/python${PYTHON_MAJMIN}/ntpath.py", + "${libdir}/python${PYTHON_MAJMIN}/opcode.py", + "${libdir}/python${PYTHON_MAJMIN}/operator.py", + "${libdir}/python${PYTHON_MAJMIN}/optparse.py", + "${libdir}/python${PYTHON_MAJMIN}/os.py", + "${libdir}/python${PYTHON_MAJMIN}/pathlib.py", + "${libdir}/python${PYTHON_MAJMIN}/pkgutil.py", + "${libdir}/python${PYTHON_MAJMIN}/platform.py", + "${libdir}/python${PYTHON_MAJMIN}/posixpath.py", + "${libdir}/python${PYTHON_MAJMIN}/re", + "${libdir}/python${PYTHON_MAJMIN}/re/_casefix.py", + "${libdir}/python${PYTHON_MAJMIN}/re/_compiler.py", + "${libdir}/python${PYTHON_MAJMIN}/re/_constants.py", + "${libdir}/python${PYTHON_MAJMIN}/re/_parser.py", + "${libdir}/python${PYTHON_MAJMIN}/reprlib.py", + "${libdir}/python${PYTHON_MAJMIN}/rlcompleter.py", + "${libdir}/python${PYTHON_MAJMIN}/runpy.py", + "${libdir}/python${PYTHON_MAJMIN}/selectors.py", + "${libdir}/python${PYTHON_MAJMIN}/shutil.py", + "${libdir}/python${PYTHON_MAJMIN}/signal.py", + "${libdir}/python${PYTHON_MAJMIN}/site.py", + "${libdir}/python${PYTHON_MAJMIN}/sitecustomize.py", + "${libdir}/python${PYTHON_MAJMIN}/sre_compile.py", + "${libdir}/python${PYTHON_MAJMIN}/sre_constants.py", + "${libdir}/python${PYTHON_MAJMIN}/sre_parse.py", + "${libdir}/python${PYTHON_MAJMIN}/stat.py", + "${libdir}/python${PYTHON_MAJMIN}/stringprep.py", + "${libdir}/python${PYTHON_MAJMIN}/struct.py", + "${libdir}/python${PYTHON_MAJMIN}/subprocess.py", + "${libdir}/python${PYTHON_MAJMIN}/symbol.py", + "${libdir}/python${PYTHON_MAJMIN}/sysconfig.py", + "${libdir}/python${PYTHON_MAJMIN}/textwrap.py", + "${libdir}/python${PYTHON_MAJMIN}/threading.py", + "${libdir}/python${PYTHON_MAJMIN}/token.py", + "${libdir}/python${PYTHON_MAJMIN}/tokenize.py", + "${libdir}/python${PYTHON_MAJMIN}/traceback.py", + "${libdir}/python${PYTHON_MAJMIN}/types.py", + "${libdir}/python${PYTHON_MAJMIN}/typing.py", + "${libdir}/python${PYTHON_MAJMIN}/urllib", + "${libdir}/python${PYTHON_MAJMIN}/urllib/parse.py", + "${libdir}/python${PYTHON_MAJMIN}/warnings.py", + "${libdir}/python${PYTHON_MAJMIN}/weakref.py", + "${libdir}/python${PYTHON_MAJMIN}/zipimport.py", + "${prefix}/lib/python${PYTHON_MAJMIN}/config*/*[!.a]" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/__future__.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/_bootlocale.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/_collections_abc.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/_compression.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/_markupbase.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/_sitebuiltins.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/_sysconfigdata*.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/_weakrefset.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/abc.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/argparse.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/ast.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/bisect.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/bz2.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/code.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/codecs.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/codeop.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/configparser.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/contextlib.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/copy.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/copyreg.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/csv.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/dataclasses.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/dis.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/enum.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/fnmatch.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/functools.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/genericpath.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/getopt.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/gettext.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/heapq.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/imp.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/inspect.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/io.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/ipaddress.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/keyword.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/linecache.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/locale.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/lzma.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/ntpath.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/opcode.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/operator.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/optparse.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/os.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/pathlib.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/pkgutil.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/platform.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/posixpath.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/re.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/reprlib.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/rlcompleter.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/runpy.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/selectors.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/shutil.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/signal.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/site.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/sre_compile.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/sre_constants.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/sre_parse.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/stat.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/stringprep.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/struct.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/subprocess.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/symbol.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/sysconfig.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/textwrap.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/threading.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/token.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/tokenize.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/traceback.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/types.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/typing.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/warnings.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/weakref.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/collections/__pycache__", + "${libdir}/python${PYTHON_MAJMIN}/collections/__pycache__/abc.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/encodings/__pycache__", + "${libdir}/python${PYTHON_MAJMIN}/encodings/__pycache__/aliases.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/encodings/__pycache__/latin_1.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/encodings/__pycache__/utf_8.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/importlib/__pycache__", + "${libdir}/python${PYTHON_MAJMIN}/importlib/__pycache__/_abc.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/importlib/__pycache__/abc.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/importlib/__pycache__/machinery.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/importlib/__pycache__/util.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/re/__pycache__", + "${libdir}/python${PYTHON_MAJMIN}/re/__pycache__/_casefix.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/re/__pycache__/_compiler.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/re/__pycache__/_constants.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/re/__pycache__/_parser.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/urllib/__pycache__", + "${libdir}/python${PYTHON_MAJMIN}/urllib/__pycache__/parse.*.pyc" + ] + }, + "crypt": { + "summary": "Python basic cryptographic and hashing support", + "rdepends": [ + "core", + "math", + "stringold" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/crypt.py", + "${libdir}/python${PYTHON_MAJMIN}/hashlib.py", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_blake2.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_crypt.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_hashlib.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_md5.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_sha1.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_sha2.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_sha3.*.so" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/crypt.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/hashlib.*.pyc" + ] + }, + "ctypes": { + "summary": "Python C types support", + "rdepends": [ + "core", + "crypt", + "io", + "math" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/ctypes", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_ctypes.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_ctypes_test.*.so" + ], + "cached": [] + }, + "curses": { + "summary": "Python curses support", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/curses", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_curses.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_curses_panel.*.so" + ], + "cached": [] + }, + "datetime": { + "summary": "Python calendar and time support", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/_strptime.py", + "${libdir}/python${PYTHON_MAJMIN}/calendar.py", + "${libdir}/python${PYTHON_MAJMIN}/datetime.py", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_datetime.*.so" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/_strptime.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/calendar.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/datetime.*.pyc" + ] + }, + "db": { + "summary": "Python file-based database support", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/dbm", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_dbm.*.so" + ], + "cached": [] + }, + "debugger": { + "summary": "Python debugger", + "rdepends": [ + "core", + "pprint", + "shell", + "stringold" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/bdb.py", + "${libdir}/python${PYTHON_MAJMIN}/pdb.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/bdb.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/pdb.*.pyc" + ] + }, + "dev": { + "cached": [], + "files": [ + "${base_libdir}/*.a", + "${base_libdir}/*.o", + "${bindir}/python*-config*", + "${datadir}/aclocal", + "${datadir}/pkgconfig", + "${includedir}", + "${libdir}/*.a", + "${libdir}/*.la", + "${libdir}/*.o", + "${libdir}/lib*${SOLIBSDEV}", + "${libdir}/pkgconfig" + ], + "rdepends": [ + "core" + ], + "summary": "Python development package" + }, + "difflib": { + "summary": "Python helpers for computing deltas between objects", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/difflib.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/difflib.*.pyc" + ] + }, + "doctest": { + "summary": "Python framework for running examples in docstrings", + "rdepends": [ + "core", + "debugger", + "difflib", + "pprint", + "shell", + "stringold", + "unittest" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/doctest.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/doctest.*.pyc" + ] + }, + "email": { + "summary": "Python email support", + "rdepends": [ + "core", + "crypt", + "datetime", + "io", + "math", + "mime", + "netclient", + "stringold" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/email", + "${libdir}/python${PYTHON_MAJMIN}/imaplib.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/imaplib.*.pyc" + ] + }, + "ensurepip": { + "summary": "Support for bootstrapping the pip installer", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/ensurepip/" + ], + "cached": [] + }, + "fcntl": { + "summary": "Python's fcntl interface", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/fcntl.*.so" + ], + "cached": [] + }, + "gdbm": { + "summary": "Python GNU database support", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_gdbm.*.so" + ], + "cached": [] + }, + "html": { + "summary": "Python HTML processing support", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/html" + ], + "cached": [] + }, + "idle": { + "summary": "Python Integrated Development Environment", + "rdepends": [ + "core" + ], + "files": [ + "${bindir}/idle*", + "${libdir}/python${PYTHON_MAJMIN}/idlelib" + ], + "cached": [] + }, + "image": { + "summary": "Python graphical image handling", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/colorsys.py", + "${libdir}/python${PYTHON_MAJMIN}/imghdr.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/colorsys.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/imghdr.*.pyc" + ] + }, + "io": { + "summary": "Python low-level I/O", + "rdepends": [ + "core", + "crypt", + "math", + "netclient", + "shell" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/_pyio.py", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_socket.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_ssl.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/termios.*.so", + "${libdir}/python${PYTHON_MAJMIN}/pipes.py", + "${libdir}/python${PYTHON_MAJMIN}/socket.py", + "${libdir}/python${PYTHON_MAJMIN}/ssl.py", + "${libdir}/python${PYTHON_MAJMIN}/tempfile.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/_pyio.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/pipes.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/socket.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/ssl.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/tempfile.*.pyc" + ] + }, + "json": { + "summary": "Python JSON support", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/json", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_json.*.so" + ], + "cached": [] + }, + "logging": { + "summary": "Python logging support", + "rdepends": [ + "core", + "io", + "netserver", + "pickle", + "stringold", + "threading" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/logging" + ], + "cached": [] + }, + "mailbox": { + "summary": "Python mailbox format support", + "rdepends": [ + "core", + "crypt", + "datetime", + "email", + "io", + "math", + "mime", + "netclient", + "stringold" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/mailbox.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/mailbox.*.pyc" + ] + }, + "math": { + "summary": "Python math support", + "rdepends": [ + "core", + "crypt" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_random.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/cmath.*.so", + "${libdir}/python${PYTHON_MAJMIN}/random.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/random.*.pyc" + ] + }, + "mime": { + "summary": "Python MIME handling APIs", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/quopri.py", + "${libdir}/python${PYTHON_MAJMIN}/uu.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/quopri.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/uu.*.pyc" + ] + }, + "mmap": { + "summary": "Python memory-mapped file support", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/mmap.*.so" + ], + "cached": [] + }, + "modules": { + "cached": [], + "files": [], + "rdepends": [ + "2to3", + "asyncio", + "audio", + "codecs", + "compile", + "compression", + "core", + "crypt", + "ctypes", + "curses", + "datetime", + "db", + "debugger", + "difflib", + "doctest", + "email", + "ensurepip", + "fcntl", + "html", + "idle", + "image", + "io", + "json", + "logging", + "mailbox", + "math", + "mime", + "mmap", + "multiprocessing", + "netclient", + "netserver", + "numbers", + "pickle", + "pkgutil", + "plistlib", + "pprint", + "profile", + "pydoc", + "resource", + "shell", + "sqlite3", + "statistics", + "stringold", + "syslog", + "terminal", + "threading", + "tkinter", + "tomllib", + "unittest", + "unixadmin", + "venv", + "xml", + "xmlrpc", + "zoneinfo" + ], + "summary": "All Python modules" + }, + "multiprocessing": { + "summary": "Python multiprocessing support", + "rdepends": [ + "core", + "crypt", + "ctypes", + "io", + "math", + "mmap", + "netclient", + "pickle", + "threading" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_multiprocessing.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_posixshmem.*.so", + "${libdir}/python${PYTHON_MAJMIN}/multiprocessing" + ], + "cached": [] + }, + "netclient": { + "summary": "Python Internet Protocol clients", + "rdepends": [ + "core", + "crypt", + "datetime", + "email", + "io", + "math", + "mime", + "stringold" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/base64.py", + "${libdir}/python${PYTHON_MAJMIN}/ftplib.py", + "${libdir}/python${PYTHON_MAJMIN}/hmac.py", + "${libdir}/python${PYTHON_MAJMIN}/http", + "${libdir}/python${PYTHON_MAJMIN}/http/__pycache__", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_uuid.*.so", + "${libdir}/python${PYTHON_MAJMIN}/mimetypes.py", + "${libdir}/python${PYTHON_MAJMIN}/nntplib.py", + "${libdir}/python${PYTHON_MAJMIN}/poplib.py", + "${libdir}/python${PYTHON_MAJMIN}/secrets.py", + "${libdir}/python${PYTHON_MAJMIN}/smtplib.py", + "${libdir}/python${PYTHON_MAJMIN}/telnetlib.py", + "${libdir}/python${PYTHON_MAJMIN}/urllib", + "${libdir}/python${PYTHON_MAJMIN}/uuid.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/base64.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/ftplib.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/hmac.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/mimetypes.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/nntplib.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/poplib.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/secrets.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/smtplib.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/telnetlib.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/uuid.*.pyc" + ] + }, + "netserver": { + "summary": "Python Internet Protocol servers", + "rdepends": [ + "core", + "crypt", + "datetime", + "email", + "html", + "io", + "math", + "mime", + "netclient", + "stringold" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/cgi.py", + "${libdir}/python${PYTHON_MAJMIN}/socketserver.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/cgi.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/socketserver.*.pyc" + ] + }, + "numbers": { + "summary": "Python number APIs", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/_pydecimal.py", + "${libdir}/python${PYTHON_MAJMIN}/contextvars.py", + "${libdir}/python${PYTHON_MAJMIN}/decimal.py", + "${libdir}/python${PYTHON_MAJMIN}/fractions.py", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_contextvars.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_decimal.*.so", + "${libdir}/python${PYTHON_MAJMIN}/numbers.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/_pydecimal.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/contextvars.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/decimal.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/fractions.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/numbers.*.pyc" + ] + }, + "pickle": { + "summary": "Python serialisation/persistence support", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/_compat_pickle.py", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_pickle.*.so", + "${libdir}/python${PYTHON_MAJMIN}/pickle.py", + "${libdir}/python${PYTHON_MAJMIN}/pickletools.py", + "${libdir}/python${PYTHON_MAJMIN}/shelve.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/_compat_pickle.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/pickle.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/pickletools.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/shelve.*.pyc" + ] + }, + "pkgutil": { + "summary": "Python package extension utility support", + "rdepends": [ + "core" + ], + "files": [], + "cached": [] + }, + "plistlib": { + "summary": "Generate and parse Mac OS X .plist files", + "rdepends": [ + "core", + "datetime", + "xml" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/plistlib.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/plistlib.*.pyc" + ] + }, + "pprint": { + "summary": "Python pretty-print support", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/pprint.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/pprint.*.pyc" + ] + }, + "profile": { + "summary": "Python basic performance profiling support", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/cProfile.py", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_lsprof.*.so", + "${libdir}/python${PYTHON_MAJMIN}/profile.py", + "${libdir}/python${PYTHON_MAJMIN}/pstats.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/cProfile.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/profile.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/pstats.*.pyc" + ] + }, + "pydoc": { + "summary": "Python interactive help support", + "rdepends": [ + "core" + ], + "files": [ + "${bindir}/pydoc*", + "${libdir}/python${PYTHON_MAJMIN}/pydoc.py", + "${libdir}/python${PYTHON_MAJMIN}/pydoc_data" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/pydoc.*.pyc" + ] + }, + "resource": { + "summary": "Python resource control interface", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/resource.*.so" + ], + "cached": [] + }, + "shell": { + "summary": "Python shell-like functionality", + "rdepends": [ + "core", + "stringold" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/cmd.py", + "${libdir}/python${PYTHON_MAJMIN}/glob.py", + "${libdir}/python${PYTHON_MAJMIN}/shlex.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/cmd.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/glob.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/shlex.*.pyc" + ] + }, + "sqlite3": { + "summary": "Python Sqlite3 database support", + "rdepends": [ + "core", + "datetime" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_sqlite3.*.so", + "${libdir}/python${PYTHON_MAJMIN}/sqlite3" + ], + "cached": [] + }, + "statistics": { + "summary": "Basic statistics module", + "rdepends": [ + "core", + "crypt", + "math", + "numbers" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_statistics.*.so", + "${libdir}/python${PYTHON_MAJMIN}/statistics.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/statistics.*.pyc" + ] + }, + "stringold": { + "summary": "Python string APIs [deprecated]", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/string.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/string.*.pyc" + ] + }, + "syslog": { + "summary": "Python syslog interface", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/syslog.*.so" + ], + "cached": [] + }, + "terminal": { + "summary": "Python terminal controlling support", + "rdepends": [ + "core", + "io" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/pty.py", + "${libdir}/python${PYTHON_MAJMIN}/tty.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/pty.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/tty.*.pyc" + ] + }, + "threading": { + "summary": "Python threading & synchronization support", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/_threading_local.py", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_queue.*.so", + "${libdir}/python${PYTHON_MAJMIN}/queue.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/_threading_local.*.pyc", + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/queue.*.pyc" + ] + }, + "tkinter": { + "summary": "Python Tcl/Tk bindings", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_tkinter.*.so", + "${libdir}/python${PYTHON_MAJMIN}/tkinter" + ], + "cached": [] + }, + "tomllib": { + "summary": "Provides an interface for parsing TOML", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/tomllib/" + ], + "cached": [] + }, + "turtle": { + "summary": "Turtle graphics is a popular way for introducing programming to kids.", + "rdepends": [ + "tkinter" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/turtle.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/turtle.*.pyc" + ] + }, + "unittest": { + "summary": "Python unit testing framework", + "rdepends": [ + "asyncio", + "core", + "difflib", + "io", + "logging", + "netclient", + "numbers", + "pprint", + "stringold" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/unittest", + "${libdir}/python${PYTHON_MAJMIN}/unittest/", + "${libdir}/python${PYTHON_MAJMIN}/unittest/__pycache__" + ], + "cached": [] + }, + "unixadmin": { + "summary": "Python Unix administration support", + "rdepends": [ + "core", + "io" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/getpass.py", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/nis.*.so" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/getpass.*.pyc" + ] + }, + "venv": { + "summary": "Provides support for creating lightweight virtual environments with their own site directories, optionally isolated from system site directories.", + "rdepends": [ + "core", + "logging", + "stringold" + ], + "files": [ + "${bindir}/pyvenv*", + "${libdir}/python${PYTHON_MAJMIN}/venv" + ], + "cached": [] + }, + "xml": { + "summary": "Python basic XML support", + "rdepends": [ + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_elementtree.*.so", + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/pyexpat.*.so", + "${libdir}/python${PYTHON_MAJMIN}/xml" + ], + "cached": [] + }, + "xmlrpc": { + "summary": "Python XML-RPC support", + "rdepends": [ + "compression", + "core", + "crypt", + "datetime", + "email", + "html", + "io", + "math", + "mime", + "netclient", + "netserver", + "numbers", + "pydoc", + "stringold", + "xml" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/xmlrpc", + "${libdir}/python${PYTHON_MAJMIN}/xmlrpc/__pycache__" + ], + "cached": [] + }, + "zipapp": { + "summary": "Tools to manage the creation of zip files containing Python code", + "rdepends": [ + "compression", + "core" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/zipapp.py" + ], + "cached": [ + "${libdir}/python${PYTHON_MAJMIN}/__pycache__/zipapp.*.pyc" + ] + }, + "zoneinfo": { + "summary": "IANA time zone support", + "rdepends": [ + "core", + "datetime" + ], + "files": [ + "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_zoneinfo.*.so", + "${libdir}/python${PYTHON_MAJMIN}/zoneinfo" + ], + "cached": [] + } +} diff --git a/meta/recipes-devtools/python/python3/python3-use-CROSSPYTHONPATH-for-PYTHON_FOR_BUILD.patch b/meta/recipes-devtools/python/python3/python3-use-CROSSPYTHONPATH-for-PYTHON_FOR_BUILD.patch deleted file mode 100644 index 74490d93a5..0000000000 --- a/meta/recipes-devtools/python/python3/python3-use-CROSSPYTHONPATH-for-PYTHON_FOR_BUILD.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 53ed216d7bf70dd2a925432b6805a701e5fc3e0e Mon Sep 17 00:00:00 2001 -From: Jackie Huang <jackie.huang@windriver.com> -Date: Mon, 17 Nov 2014 06:44:47 +0000 -Subject: [PATCH] python3 use CROSSPYTHONPATH for PYTHON_FOR_BUILD - -Upstream-Status: Inappropriate [Cross compile specific] - -Signed-off-by: Jackie Huang <jackie.huang@windriver.com> ---- - configure.ac | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index 989baf9..2890c96 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -67,7 +67,7 @@ if test "$cross_compiling" = yes; then - AC_MSG_ERROR([python$PACKAGE_VERSION interpreter not found]) - fi - AC_MSG_RESULT($interp) -- PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`:)$(srcdir)/Lib:$(srcdir)/Lib/$(PLATDIR) '$interp -+ PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(CROSSPYTHONPATH) '$interp - fi - elif test "$cross_compiling" = maybe; then - AC_MSG_ERROR([Cross compiling required --host=HOST-TUPLE and --build=ARCH]) --- -2.0.1 - diff --git a/meta/recipes-devtools/python/python3/reformat_sysconfig.py b/meta/recipes-devtools/python/python3/reformat_sysconfig.py new file mode 100644 index 0000000000..5e2b12879d --- /dev/null +++ b/meta/recipes-devtools/python/python3/reformat_sysconfig.py @@ -0,0 +1,21 @@ +#! /usr/bin/env python3 +# +# SPDX-License-Identifier: MIT +# +# Copyright 2019 by Garmin Ltd. or its subsidiaries +# +# A script to reformat python sysconfig + +import sys +import pprint +l = {} +g = {} +with open(sys.argv[1], 'r') as f: + exec(f.read(), g, l) + +with open(sys.argv[1], 'w') as f: + for k in sorted(l.keys()): + f.write('%s = ' % k) + pprint.pprint(l[k], stream=f, width=1) + f.write('\n') + diff --git a/meta/recipes-devtools/python/python3/run-ptest b/meta/recipes-devtools/python/python3/run-ptest new file mode 100644 index 0000000000..d1c26c11e2 --- /dev/null +++ b/meta/recipes-devtools/python/python3/run-ptest @@ -0,0 +1,3 @@ +#!/bin/sh +SKIPPED_TESTS= +{ SETUPTOOLS_USE_DISTUTILS=nonlocal python3 -m test $SKIPPED_TESTS -v -j 4 || echo "FAIL: python3" ; } | sed -u -e '/\.\.\. ok/ s/^/PASS: /g' -r -e '/\.\.\. (ERROR|FAIL)/ s/^/FAIL: /g' -e '/\.\.\. skipped/ s/^/SKIP: /g' -e 's/ \.\.\. ok//g' -e 's/ \.\.\. ERROR//g' -e 's/ \.\.\. FAIL//g' -e 's/ \.\.\. skipped//g' diff --git a/meta/recipes-devtools/python/python3/setup.py-check-cross_compiling-when-get-FLAGS.patch b/meta/recipes-devtools/python/python3/setup.py-check-cross_compiling-when-get-FLAGS.patch deleted file mode 100644 index fc2e12dfe5..0000000000 --- a/meta/recipes-devtools/python/python3/setup.py-check-cross_compiling-when-get-FLAGS.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 8dad810f3a3d073f09ad72e1a3ee0a895eab2ca1 Mon Sep 17 00:00:00 2001 -From: Robert Yang <liezhi.yang@windriver.com> -Date: Sun, 18 Jan 2015 19:05:36 -0800 -Subject: [PATCH] setup.py:check cross_compiling when get FLAGS - -Fixed when compile target pythnon3: -gcc -isystem/path/to/sysroots/x86_64-linux/usr/include \ - -L=/path/to/sysroots/x86_64-linux/usr/lib - -This is incorrect, the native sysroot should not be used by target -python3. - -Upstream-Status: Pending - -Signed-off-by: Robert Yang <liezhi.yang@windriver.com> ---- - setup.py | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/setup.py b/setup.py -index e8339cd..83fd31f 100644 ---- a/setup.py -+++ b/setup.py -@@ -238,7 +238,10 @@ class PyBuildExt(build_ext): - # unfortunately, distutils doesn't let us provide separate C and C++ - # compilers - if compiler is not None: -- (ccshared,cflags) = sysconfig.get_config_vars('CCSHARED','CFLAGS') -+ if cross_compiling: -+ (ccshared,cflags) = (os.environ.get('CCSHARED') or '', os.environ.get('CFLAGS') or '') -+ else: -+ (ccshared,cflags) = sysconfig.get_config_vars('CCSHARED','CFLAGS') - args['compiler_so'] = compiler + ' ' + ccshared + ' ' + cflags - self.compiler.set_executables(**args) - -@@ -457,7 +460,10 @@ class PyBuildExt(build_ext): - ('LDFLAGS', '-R', self.compiler.runtime_library_dirs), - ('LDFLAGS', '-L', self.compiler.library_dirs), - ('CPPFLAGS', '-I', self.compiler.include_dirs)): -- env_val = sysconfig.get_config_var(env_var) -+ if cross_compiling: -+ env_val = os.environ.get(env_var) -+ else: -+ env_val = sysconfig.get_config_var(env_var) - if env_val: - # To prevent optparse from raising an exception about any - # options in env_val that it doesn't know about we strip out --- -1.7.9.5 - diff --git a/meta/recipes-devtools/python/python3/setuptweaks.patch b/meta/recipes-devtools/python/python3/setuptweaks.patch deleted file mode 100644 index 3a91b1916c..0000000000 --- a/meta/recipes-devtools/python/python3/setuptweaks.patch +++ /dev/null @@ -1,57 +0,0 @@ -This patch removes various ways native system options can pass into the python -compilation and somehow break C modules. - -Upstream-Status: Inappropriate [OE Specific] - -RP 2012/04/23 - -Index: Python-2.7.2/setup.py -=================================================================== ---- Python-2.7.2.orig/setup.py 2012-04-23 20:03:47.295582553 +0000 -+++ Python-2.7.2/setup.py 2012-04-23 20:03:15.000000000 +0000 -@@ -231,7 +231,13 @@ - # compilers - if compiler is not None: - (ccshared,cflags) = sysconfig.get_config_vars('CCSHARED','CFLAGS') -- args['compiler_so'] = compiler + ' ' + ccshared + ' ' + cflags -+ # Need to filter out -isysroot from the flags. Ideally should -+ # figure out target flags here. -+ flags = [] -+ for f in cflags.split(): -+ if not f.startswith("-isystem"): -+ flags.append(f) -+ args['compiler_so'] = compiler + ' ' + ccshared + ' ' + ' '.join(flags) - self.compiler.set_executables(**args) - - build_ext.build_extensions(self) -@@ -393,7 +399,6 @@ - # into configure and stored in the Makefile (issue found on OS X 10.3). - for env_var, arg_name, dir_list in ( - ('LDFLAGS', '-R', self.compiler.runtime_library_dirs), -- ('LDFLAGS', '-L', self.compiler.library_dirs), - ('CPPFLAGS', '-I', self.compiler.include_dirs)): - env_val = sysconfig.get_config_var(env_var) - if env_val: -@@ -419,16 +424,16 @@ - for directory in reversed(options.dirs): - add_dir_to_list(dir_list, directory) - -- if os.path.normpath(sys.prefix) != '/usr' \ -- and not sysconfig.get_config_var('PYTHONFRAMEWORK'): -+# if os.path.normpath(sys.prefix) != '/usr' \ -+# and not sysconfig.get_config_var('PYTHONFRAMEWORK'): - # OSX note: Don't add LIBDIR and INCLUDEDIR to building a framework - # (PYTHONFRAMEWORK is set) to avoid # linking problems when - # building a framework with different architectures than - # the one that is currently installed (issue #7473) -- add_dir_to_list(self.compiler.library_dirs, -- sysconfig.get_config_var("LIBDIR")) -- add_dir_to_list(self.compiler.include_dirs, -- sysconfig.get_config_var("INCLUDEDIR")) -+# add_dir_to_list(self.compiler.library_dirs, -+# sysconfig.get_config_var("LIBDIR")) -+# add_dir_to_list(self.compiler.include_dirs, -+# sysconfig.get_config_var("INCLUDEDIR")) - - try: - have_unicode = unicode diff --git a/meta/recipes-devtools/python/python3/shutil-follow-symlink-fix.patch b/meta/recipes-devtools/python/python3/shutil-follow-symlink-fix.patch deleted file mode 100644 index 802b1c7203..0000000000 --- a/meta/recipes-devtools/python/python3/shutil-follow-symlink-fix.patch +++ /dev/null @@ -1,17 +0,0 @@ -shutils should consider symlinks - --Khem - -Upstream-Status: Pending - ---- a/Lib/shutil.py 2013-01-29 12:31:06.926555779 -0800 -+++ b/Lib/shutil.py 2013-01-29 16:31:39.097554182 -0800 -@@ -132,7 +132,7 @@ def copymode(src, dst, *, follow_symlink - st = stat_func(src) - chmod_func(dst, stat.S_IMODE(st.st_mode)) - --if hasattr(os, 'listxattr'): -+if hasattr(os, 'listxattr') and os.listxattr in os.supports_follow_symlinks: - def _copyxattr(src, dst, *, follow_symlinks=True): - """Copy extended filesystem attributes from `src` to `dst`. - diff --git a/meta/recipes-devtools/python/python3/sitecustomize.py b/meta/recipes-devtools/python/python3/sitecustomize.py deleted file mode 100644 index 4c8b5e2ba3..0000000000 --- a/meta/recipes-devtools/python/python3/sitecustomize.py +++ /dev/null @@ -1,37 +0,0 @@ -# OpenEmbedded sitecustomize.py (C) 2002-2008 Michael 'Mickey' Lauer <mlauer@vanille-media.de> -# GPLv2 or later -# Version: 20081123 -# Features: -# * set proper default encoding -# * enable readline completion in the interactive interpreter -# * load command line history on startup -# * save command line history on exit - -import os - -def __exithandler(): - try: - readline.write_history_file( "%s/.python-history" % os.getenv( "HOME", "/tmp" ) ) - except IOError: - pass - -def __registerExitHandler(): - import atexit - atexit.register( __exithandler ) - -def __enableReadlineSupport(): - readline.set_history_length( 1000 ) - readline.parse_and_bind( "tab: complete" ) - try: - readline.read_history_file( "%s/.python-history" % os.getenv( "HOME", "/tmp" ) ) - except IOError: - pass - -import sys -try: - import rlcompleter, readline -except ImportError: - pass -else: - __registerExitHandler() - __enableReadlineSupport() diff --git a/meta/recipes-devtools/python/python3/support_SOURCE_DATE_EPOCH_in_py_compile.patch b/meta/recipes-devtools/python/python3/support_SOURCE_DATE_EPOCH_in_py_compile.patch deleted file mode 100644 index 32ecab9fec..0000000000 --- a/meta/recipes-devtools/python/python3/support_SOURCE_DATE_EPOCH_in_py_compile.patch +++ /dev/null @@ -1,97 +0,0 @@ -The compiled .pyc files contain time stamp corresponding to the compile time. -This prevents binary reproducibility. This patch allows to achieve binary -reproducibility by overriding the build time stamp by the value -exported via SOURCE_DATE_EPOCH. - -Upstream-Status: Backport - -Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> - - -From aeab488630fdb1b56a8d0b0c13fa88706b2afe9b Mon Sep 17 00:00:00 2001 -From: "Bernhard M. Wiedemann" <bwiedemann@suse.de> -Date: Sat, 25 Feb 2017 06:42:28 +0100 -Subject: [PATCH] bpo-29708: support SOURCE_DATE_EPOCH env var in py_compile - -to allow for reproducible builds of python packages - -See https://reproducible-builds.org/ for why this is good -and https://reproducible-builds.org/specs/source-date-epoch/ -for the definition of this variable. - -Background: -In some distributions like openSUSE, binary rpms contain precompiled .pyc files. - -And packages like amqp or twisted dynamically generate .py files at build time -so those have the current time and that timestamp gets embedded -into the .pyc file header. -When we then adapt file timestamps in rpms to be constant, -the timestamp in the .pyc header will no more match -the .py timestamp in the filesystem. -The software will still work, but it will not use the .pyc file as it should. ---- - Doc/library/py_compile.rst | 4 ++++ - Lib/py_compile.py | 4 ++++ - Lib/test/test_py_compile.py | 19 +++++++++++++++++++ - 3 files changed, 27 insertions(+) - -diff --git a/Doc/library/py_compile.rst b/Doc/library/py_compile.rst -index 0af8fb1..841f3e8 100644 ---- a/Doc/library/py_compile.rst -+++ b/Doc/library/py_compile.rst -@@ -53,6 +53,10 @@ byte-code cache files in the directory containing the source code. - :func:`compile` function. The default of ``-1`` selects the optimization - level of the current interpreter. - -+ If the SOURCE_DATE_EPOCH environment variable is set, the .py file mtime -+ and timestamp entry in .pyc file header, will be limited to this value. -+ See https://reproducible-builds.org/specs/source-date-epoch/ for more info. -+ - .. versionchanged:: 3.2 - Changed default value of *cfile* to be :PEP:`3147`-compliant. Previous - default was *file* + ``'c'`` (``'o'`` if optimization was enabled). -diff --git a/Lib/py_compile.py b/Lib/py_compile.py -index 11c5b50..62dcdc7 100644 ---- a/Lib/py_compile.py -+++ b/Lib/py_compile.py -@@ -137,6 +137,10 @@ def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1): - except FileExistsError: - pass - source_stats = loader.path_stats(file) -+ sde = os.environ.get('SOURCE_DATE_EPOCH') -+ if sde and source_stats['mtime'] > int(sde): -+ source_stats['mtime'] = int(sde) -+ os.utime(file, (source_stats['mtime'], source_stats['mtime'])) - bytecode = importlib._bootstrap_external._code_to_bytecode( - code, source_stats['mtime'], source_stats['size']) - mode = importlib._bootstrap_external._calc_mode(file) -diff --git a/Lib/test/test_py_compile.py b/Lib/test/test_py_compile.py -index 4a6caa5..3d09963 100644 ---- a/Lib/test/test_py_compile.py -+++ b/Lib/test/test_py_compile.py -@@ -98,6 +98,25 @@ def test_bad_coding(self): - self.assertFalse(os.path.exists( - importlib.util.cache_from_source(bad_coding))) - -+ def test_source_date_epoch(self): -+ testtime = 123456789 -+ orig_sde = os.getenv("SOURCE_DATE_EPOCH") -+ os.environ["SOURCE_DATE_EPOCH"] = str(testtime) -+ py_compile.compile(self.source_path, self.pyc_path) -+ if orig_sde: -+ os.environ["SOURCE_DATE_EPOCH"] = orig_sde -+ else: -+ del os.environ["SOURCE_DATE_EPOCH"] -+ self.assertTrue(os.path.exists(self.pyc_path)) -+ self.assertFalse(os.path.exists(self.cache_path)) -+ statinfo = os.stat(self.source_path) -+ self.assertEqual(statinfo.st_mtime, testtime) -+ f = open(self.pyc_path, "rb") -+ f.read(4) -+ timebytes = f.read(4) # read timestamp from pyc header -+ f.close() -+ self.assertEqual(timebytes, (testtime).to_bytes(4, 'little')) -+ - @unittest.skipIf(sys.flags.optimize > 0, 'test does not work with -O') - def test_double_dot_no_clobber(self): - # http://bugs.python.org/issue22966 diff --git a/meta/recipes-devtools/python/python3/sysconfig.py-add-_PYTHON_PROJECT_SRC.patch b/meta/recipes-devtools/python/python3/sysconfig.py-add-_PYTHON_PROJECT_SRC.patch deleted file mode 100644 index de07643f2b..0000000000 --- a/meta/recipes-devtools/python/python3/sysconfig.py-add-_PYTHON_PROJECT_SRC.patch +++ /dev/null @@ -1,54 +0,0 @@ -From fc93b3cc23b4f9698ae92a42986dbb02b6f19588 Mon Sep 17 00:00:00 2001 -From: Robert Yang <liezhi.yang@windriver.com> -Date: Sun, 18 Jan 2015 06:29:50 -0800 -Subject: [PATCH] sysconfig.py: add _PYTHON_PROJECT_SRC - -python3 has introduced _PYTHON_PROJECT_BASE which is used for separate B -and S, but it doesn't work when compile Modules, the target python3 runs -python3-native's sysconfig to get srcdir which is the native's, there -would be errors when native's srcdir has been removed, add -_PYTHON_PROJECT_SRC to fix the problem. - -Upstream-Status: Pending - -Signed-off-by: Robert Yang <liezhi.yang@windriver.com> ---- - Lib/distutils/sysconfig.py | 5 ++++- - Lib/sysconfig.py | 5 ++++- - 2 files changed, 8 insertions(+), 2 deletions(-) - -diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py -index a545ab9..74317d1 100644 ---- a/Lib/distutils/sysconfig.py -+++ b/Lib/distutils/sysconfig.py -@@ -554,7 +554,10 @@ def get_config_vars(*args): - _config_vars['exec_prefix'] = EXEC_PREFIX - - # Always convert srcdir to an absolute path -- srcdir = _config_vars.get('srcdir', project_base) -+ if "_PYTHON_PROJECT_SRC" in os.environ: -+ srcdir = os.path.abspath(os.environ["_PYTHON_PROJECT_SRC"]) -+ else: -+ srcdir = _config_vars.get('srcdir', project_base) - if os.name == 'posix': - if python_build: - # If srcdir is a relative path (typically '.' or '..') -diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py -index 7287f11..cc92998 100644 ---- a/Lib/sysconfig.py -+++ b/Lib/sysconfig.py -@@ -562,7 +562,10 @@ def get_config_vars(*args): - _CONFIG_VARS['userbase'] = _getuserbase() - - # Always convert srcdir to an absolute path -- srcdir = _CONFIG_VARS.get('srcdir', _PROJECT_BASE) -+ if "_PYTHON_PROJECT_SRC" in os.environ: -+ srcdir = os.path.abspath(os.environ["_PYTHON_PROJECT_SRC"]) -+ else: -+ srcdir = _CONFIG_VARS.get('srcdir', _PROJECT_BASE) - if os.name == 'posix': - if _PYTHON_BUILD: - # If srcdir is a relative path (typically '.' or '..') --- -1.7.9.5 - diff --git a/meta/recipes-devtools/python/python3/sysroot-include-headers.patch b/meta/recipes-devtools/python/python3/sysroot-include-headers.patch deleted file mode 100644 index 785b5567f2..0000000000 --- a/meta/recipes-devtools/python/python3/sysroot-include-headers.patch +++ /dev/null @@ -1,35 +0,0 @@ -Dont search hardcoded paths, we might be doing a cross-build -Use '=' in-front to let compiler append sysroot, if it can - -Should fix things like - -configure:6972: arm-angstrom-linux-gnueabi-gcc -march=armv7-a -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a8 -DNDEBUG -fno-inline -D__SOFTFP__ --sysroot=/build/v2013.06/build/tmp-angstrom_v2013_06-eglibc/sysroots/beaglebone -c -O2 -pipe -g -feliminate-unused-debug-types -I/usr/include/ncursesw conftest.c >&5 -cc1: warning: include location "/usr/include/ncursesw" is unsafe for cross-compilation [-Wpoison-system-directories] - - -Signed-off-by: Khem Raj -Upstream-Status: Pending - - -Index: Python-3.3.2/setup.py -=================================================================== ---- Python-3.3.2.orig/setup.py 2013-07-30 01:30:48.000000000 -0700 -+++ Python-3.3.2/setup.py 2013-07-30 01:41:11.697862723 -0700 -@@ -1210,7 +1210,7 @@ - panel_library = 'panel' - if curses_library == 'ncursesw': - curses_defines.append(('HAVE_NCURSESW', '1')) -- curses_includes.append('/usr/include/ncursesw') -+ curses_includes.append('=/usr/include/ncursesw') - # Bug 1464056: If _curses.so links with ncursesw, - # _curses_panel.so must link with panelw. - panel_library = 'panelw' -@@ -1819,7 +1819,7 @@ - if host_platform == 'darwin': - # OS X 10.5 comes with libffi.dylib; the include files are - # in /usr/include/ffi -- inc_dirs.append('/usr/include/ffi') -+ inc_dirs.append('=/usr/include/ffi') - - ffi_inc = [sysconfig.get_config_var("LIBFFI_INCLUDEDIR")] - if not ffi_inc or ffi_inc[0] == '': diff --git a/meta/recipes-devtools/python/python3/tweak-MULTIARCH-for-powerpc-linux-gnuspe.patch b/meta/recipes-devtools/python/python3/tweak-MULTIARCH-for-powerpc-linux-gnuspe.patch deleted file mode 100644 index 8d037278bd..0000000000 --- a/meta/recipes-devtools/python/python3/tweak-MULTIARCH-for-powerpc-linux-gnuspe.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 5d6509313198ec9b686cad50b002212e4344004b Mon Sep 17 00:00:00 2001 -From: Hongxu Jia <hongxu.jia@windriver.com> -Date: Fri, 11 Mar 2016 01:15:45 -0500 -Subject: [PATCH] configure.ac: tweak MULTIARCH for powerpc-linux-gnuspe - -For p1022ds bsp, the MULTIARCH is powerpc-linux-gnuspev1 and -python3 did not recognize the extra 'v1' which caused python3 -configure error for the platform triplet. - -Q:Why Python3 check platform triplet? - -A:Under Linux, GNU/KFreeBSD and the Hurd, C extensions now include -the architecture triplet in the extension name, to make it easy to -test builds for different ABIs in the same working tree. - -Here is the generated C extensions which take platform triplet into account. -... -|image/usr/lib/python3.5/lib-dynload/_datetime.cpython-35m-powerpc-linux-gnuspe.so -... - -https://bugs.python.org/issue22980 -https://www.python.org/dev/peps/pep-3149/ -https://bugs.python.org/review/22980/patch/14593/54808 - -Upstream-Status: Pending - -Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> ---- - configure.ac | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/configure.ac b/configure.ac -index 9eb3d22..c34a9a0 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -724,6 +724,13 @@ fi - - - MULTIARCH=$($CC --print-multiarch 2>/dev/null) -+ -+# Tweak MULTIARCH -+if test x$MULTIARCH = xpowerpc-linux-gnuspev1 -+then -+ MULTIARCH="powerpc-linux-gnuspe" -+fi -+ - AC_SUBST(MULTIARCH) - - AC_MSG_CHECKING([for the platform triplet based on compiler characteristics]) --- -1.9.1 - diff --git a/meta/recipes-devtools/python/python3/unixccompiler.patch b/meta/recipes-devtools/python/python3/unixccompiler.patch deleted file mode 100644 index 3e2b1d1c2e..0000000000 --- a/meta/recipes-devtools/python/python3/unixccompiler.patch +++ /dev/null @@ -1,35 +0,0 @@ -Upstream-Status: Pending - -The CC variable,sometimes like:"x86_64-poky-linux-gcc -m64 --sysroot=/${TMPDIR}/sysroots/qemux86-64", contains option information. -This will lead to wrong compiler name "qemux86-64" rather than "x86_64-poky-linux-gcc" when python finding the compiler name. - -Secondly add -L=<path> this way linker will be able to resolve /usr/lib w.r.t sysroot and not -use hardcoded /usr/lib to look for libs which is wrong in cross compile environment and this will work -ok on native systems too since sysroot for native compilers is / - -Signed-off-by: Mei Lei <lei.mei@intel.com> -Signed-off-by: Khem Raj <raj.khem@gmail.com> -Index: Python-3.3.2/Lib/distutils/unixccompiler.py -=================================================================== ---- Python-3.3.2.orig/Lib/distutils/unixccompiler.py 2013-05-15 09:32:54.000000000 -0700 -+++ Python-3.3.2/Lib/distutils/unixccompiler.py 2013-08-01 00:58:18.629056286 -0700 -@@ -202,7 +202,9 @@ - # ccompiler.py. - - def library_dir_option(self, dir): -- return "-L" + dir -+ if dir.startswith("/"): -+ return "-L=" + dir -+ return "-L" + dir - - def _is_gcc(self, compiler_name): - return "gcc" in compiler_name or "g++" in compiler_name -@@ -221,7 +221,7 @@ - # this time, there's no way to determine this information from - # the configuration data stored in the Python installation, so - # we use this hack. -- compiler = os.path.basename(sysconfig.get_config_var("CC")) -+ compiler = sysconfig.get_config_var("CC") - if sys.platform[:6] == "darwin": - # MacOSX's linker doesn't understand the -R flag at all - return "-L" + dir diff --git a/meta/recipes-devtools/python/python3/upstream-random-fixes.patch b/meta/recipes-devtools/python/python3/upstream-random-fixes.patch deleted file mode 100644 index 9b40e8ac9f..0000000000 --- a/meta/recipes-devtools/python/python3/upstream-random-fixes.patch +++ /dev/null @@ -1,703 +0,0 @@ -From 035ba5da3e53e45c712b39fe1f6fb743e697c032 Mon Sep 17 00:00:00 2001 -From: Victor Stinner <victor.stinner@gmail.com> -Date: Mon, 9 Jan 2017 11:18:53 +0100 -Subject: [PATCH] Issue #29157: Prefer getrandom() over getentropy() - -Copy and then adapt Python/random.c from default branch. Difference between 3.5 -and default branches: - -* Python 3.5 only uses getrandom() in non-blocking mode: flags=GRND_NONBLOCK -* If getrandom() fails with EAGAIN: py_getrandom() immediately fails and - remembers that getrandom() doesn't work. -* Python 3.5 has no _PyOS_URandomNonblock() function: _PyOS_URandom() - works in non-blocking mode on Python 3.5 - -Upstream-Status: Backport [https://github.com/python/cpython/commit/035ba5da3e53e45c712b39fe1f6fb743e697c032] -Signed-off-by: Alexander Kanavin <alexander.kanavin@intel.com> - ---- - Python/random.c | 494 +++++++++++++++++++++++++++++++++----------------------- - 1 file changed, 294 insertions(+), 200 deletions(-) - -diff --git a/Python/random.c b/Python/random.c -index d203939..31f61d0 100644 ---- a/Python/random.c -+++ b/Python/random.c -@@ -1,6 +1,9 @@ - #include "Python.h" - #ifdef MS_WINDOWS - # include <windows.h> -+/* All sample MSDN wincrypt programs include the header below. It is at least -+ * required with Min GW. */ -+# include <wincrypt.h> - #else - # include <fcntl.h> - # ifdef HAVE_SYS_STAT_H -@@ -37,10 +40,9 @@ win32_urandom_init(int raise) - return 0; - - error: -- if (raise) -+ if (raise) { - PyErr_SetFromWindowsErr(0); -- else -- Py_FatalError("Failed to initialize Windows random API (CryptoGen)"); -+ } - return -1; - } - -@@ -53,8 +55,9 @@ win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise) - - if (hCryptProv == 0) - { -- if (win32_urandom_init(raise) == -1) -+ if (win32_urandom_init(raise) == -1) { - return -1; -+ } - } - - while (size > 0) -@@ -63,11 +66,9 @@ win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise) - if (!CryptGenRandom(hCryptProv, (DWORD)chunk, buffer)) - { - /* CryptGenRandom() failed */ -- if (raise) -+ if (raise) { - PyErr_SetFromWindowsErr(0); -- else -- Py_FatalError("Failed to initialized the randomized hash " -- "secret using CryptoGen)"); -+ } - return -1; - } - buffer += chunk; -@@ -76,58 +77,23 @@ win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise) - return 0; - } - --/* Issue #25003: Don't use getentropy() on Solaris (available since -- * Solaris 11.3), it is blocking whereas os.urandom() should not block. */ --#elif defined(HAVE_GETENTROPY) && !defined(sun) --#define PY_GETENTROPY 1 -- --/* Fill buffer with size pseudo-random bytes generated by getentropy(). -- Return 0 on success, or raise an exception and return -1 on error. -- -- If fatal is nonzero, call Py_FatalError() instead of raising an exception -- on error. */ --static int --py_getentropy(unsigned char *buffer, Py_ssize_t size, int fatal) --{ -- while (size > 0) { -- Py_ssize_t len = Py_MIN(size, 256); -- int res; -- -- if (!fatal) { -- Py_BEGIN_ALLOW_THREADS -- res = getentropy(buffer, len); -- Py_END_ALLOW_THREADS -- -- if (res < 0) { -- PyErr_SetFromErrno(PyExc_OSError); -- return -1; -- } -- } -- else { -- res = getentropy(buffer, len); -- if (res < 0) -- Py_FatalError("getentropy() failed"); -- } -- -- buffer += len; -- size -= len; -- } -- return 0; --} -- --#else -+#else /* !MS_WINDOWS */ - - #if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL) - #define PY_GETRANDOM 1 - --/* Call getrandom() -+/* Call getrandom() to get random bytes: -+ - - Return 1 on success -- - Return 0 if getrandom() syscall is not available (failed with ENOSYS or -- EPERM) or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom -- not initialized yet) and raise=0. -+ - Return 0 if getrandom() is not available (failed with ENOSYS or EPERM), -+ or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom not -+ initialized yet). - - Raise an exception (if raise is non-zero) and return -1 on error: -- getrandom() failed with EINTR and the Python signal handler raised an -- exception, or getrandom() failed with a different error. */ -+ if getrandom() failed with EINTR, raise is non-zero and the Python signal -+ handler raised an exception, or if getrandom() failed with a different -+ error. -+ -+ getrandom() is retried if it failed with EINTR: interrupted by a signal. */ - static int - py_getrandom(void *buffer, Py_ssize_t size, int raise) - { -@@ -142,16 +108,19 @@ py_getrandom(void *buffer, Py_ssize_t size, int raise) - * see https://bugs.python.org/issue26839. To avoid this, use the - * GRND_NONBLOCK flag. */ - const int flags = GRND_NONBLOCK; -+ char *dest; - long n; - - if (!getrandom_works) { - return 0; - } - -+ dest = buffer; - while (0 < size) { - #ifdef sun - /* Issue #26735: On Solaris, getrandom() is limited to returning up -- to 1024 bytes */ -+ to 1024 bytes. Call it multiple times if more bytes are -+ requested. */ - n = Py_MIN(size, 1024); - #else - n = Py_MIN(size, LONG_MAX); -@@ -161,34 +130,35 @@ py_getrandom(void *buffer, Py_ssize_t size, int raise) - #ifdef HAVE_GETRANDOM - if (raise) { - Py_BEGIN_ALLOW_THREADS -- n = getrandom(buffer, n, flags); -+ n = getrandom(dest, n, flags); - Py_END_ALLOW_THREADS - } - else { -- n = getrandom(buffer, n, flags); -+ n = getrandom(dest, n, flags); - } - #else - /* On Linux, use the syscall() function because the GNU libc doesn't -- * expose the Linux getrandom() syscall yet. See: -- * https://sourceware.org/bugzilla/show_bug.cgi?id=17252 */ -+ expose the Linux getrandom() syscall yet. See: -+ https://sourceware.org/bugzilla/show_bug.cgi?id=17252 */ - if (raise) { - Py_BEGIN_ALLOW_THREADS -- n = syscall(SYS_getrandom, buffer, n, flags); -+ n = syscall(SYS_getrandom, dest, n, flags); - Py_END_ALLOW_THREADS - } - else { -- n = syscall(SYS_getrandom, buffer, n, flags); -+ n = syscall(SYS_getrandom, dest, n, flags); - } - #endif - - if (n < 0) { -- /* ENOSYS: getrandom() syscall not supported by the kernel (but -- * maybe supported by the host which built Python). EPERM: -- * getrandom() syscall blocked by SECCOMP or something else. */ -+ /* ENOSYS: the syscall is not supported by the kernel. -+ EPERM: the syscall is blocked by a security policy (ex: SECCOMP) -+ or something else. */ - if (errno == ENOSYS || errno == EPERM) { - getrandom_works = 0; - return 0; - } -+ - if (errno == EAGAIN) { - /* getrandom(GRND_NONBLOCK) fails with EAGAIN if the system - urandom is not initialiazed yet. In this case, fall back on -@@ -202,169 +172,225 @@ py_getrandom(void *buffer, Py_ssize_t size, int raise) - } - - if (errno == EINTR) { -- if (PyErr_CheckSignals()) { -- if (!raise) { -- Py_FatalError("getrandom() interrupted by a signal"); -+ if (raise) { -+ if (PyErr_CheckSignals()) { -+ return -1; - } -- return -1; - } - -- /* retry getrandom() */ -+ /* retry getrandom() if it was interrupted by a signal */ - continue; - } - - if (raise) { - PyErr_SetFromErrno(PyExc_OSError); - } -- else { -- Py_FatalError("getrandom() failed"); -- } - return -1; - } - -- buffer += n; -+ dest += n; - size -= n; - } - return 1; - } --#endif - --static struct { -- int fd; -- dev_t st_dev; -- ino_t st_ino; --} urandom_cache = { -1 }; -+#elif defined(HAVE_GETENTROPY) -+#define PY_GETENTROPY 1 - -+/* Fill buffer with size pseudo-random bytes generated by getentropy(): - --/* Read 'size' random bytes from py_getrandom(). Fall back on reading from -- /dev/urandom if getrandom() is not available. -+ - Return 1 on success -+ - Return 0 if getentropy() syscall is not available (failed with ENOSYS or -+ EPERM). -+ - Raise an exception (if raise is non-zero) and return -1 on error: -+ if getentropy() failed with EINTR, raise is non-zero and the Python signal -+ handler raised an exception, or if getentropy() failed with a different -+ error. - -- Call Py_FatalError() on error. */ --static void --dev_urandom_noraise(unsigned char *buffer, Py_ssize_t size) -+ getentropy() is retried if it failed with EINTR: interrupted by a signal. */ -+static int -+py_getentropy(char *buffer, Py_ssize_t size, int raise) - { -- int fd; -- Py_ssize_t n; -+ /* Is getentropy() supported by the running kernel? Set to 0 if -+ getentropy() failed with ENOSYS or EPERM. */ -+ static int getentropy_works = 1; - -- assert (0 < size); -- --#ifdef PY_GETRANDOM -- if (py_getrandom(buffer, size, 0) == 1) { -- return; -+ if (!getentropy_works) { -+ return 0; - } -- /* getrandom() failed with ENOSYS or EPERM, -- fall back on reading /dev/urandom */ --#endif - -- fd = _Py_open_noraise("/dev/urandom", O_RDONLY); -- if (fd < 0) { -- Py_FatalError("Failed to open /dev/urandom"); -- } -+ while (size > 0) { -+ /* getentropy() is limited to returning up to 256 bytes. Call it -+ multiple times if more bytes are requested. */ -+ Py_ssize_t len = Py_MIN(size, 256); -+ int res; - -- while (0 < size) -- { -- do { -- n = read(fd, buffer, (size_t)size); -- } while (n < 0 && errno == EINTR); -+ if (raise) { -+ Py_BEGIN_ALLOW_THREADS -+ res = getentropy(buffer, len); -+ Py_END_ALLOW_THREADS -+ } -+ else { -+ res = getentropy(buffer, len); -+ } - -- if (n <= 0) { -- /* read() failed or returned 0 bytes */ -- Py_FatalError("Failed to read bytes from /dev/urandom"); -- break; -+ if (res < 0) { -+ /* ENOSYS: the syscall is not supported by the running kernel. -+ EPERM: the syscall is blocked by a security policy (ex: SECCOMP) -+ or something else. */ -+ if (errno == ENOSYS || errno == EPERM) { -+ getentropy_works = 0; -+ return 0; -+ } -+ -+ if (errno == EINTR) { -+ if (raise) { -+ if (PyErr_CheckSignals()) { -+ return -1; -+ } -+ } -+ -+ /* retry getentropy() if it was interrupted by a signal */ -+ continue; -+ } -+ -+ if (raise) { -+ PyErr_SetFromErrno(PyExc_OSError); -+ } -+ return -1; - } -- buffer += n; -- size -= n; -+ -+ buffer += len; -+ size -= len; - } -- close(fd); -+ return 1; - } -+#endif /* defined(HAVE_GETENTROPY) && !defined(sun) */ - --/* Read 'size' random bytes from py_getrandom(). Fall back on reading from -- /dev/urandom if getrandom() is not available. - -- Return 0 on success. Raise an exception and return -1 on error. */ -+static struct { -+ int fd; -+ dev_t st_dev; -+ ino_t st_ino; -+} urandom_cache = { -1 }; -+ -+/* Read random bytes from the /dev/urandom device: -+ -+ - Return 0 on success -+ - Raise an exception (if raise is non-zero) and return -1 on error -+ -+ Possible causes of errors: -+ -+ - open() failed with ENOENT, ENXIO, ENODEV, EACCES: the /dev/urandom device -+ was not found. For example, it was removed manually or not exposed in a -+ chroot or container. -+ - open() failed with a different error -+ - fstat() failed -+ - read() failed or returned 0 -+ -+ read() is retried if it failed with EINTR: interrupted by a signal. -+ -+ The file descriptor of the device is kept open between calls to avoid using -+ many file descriptors when run in parallel from multiple threads: -+ see the issue #18756. -+ -+ st_dev and st_ino fields of the file descriptor (from fstat()) are cached to -+ check if the file descriptor was replaced by a different file (which is -+ likely a bug in the application): see the issue #21207. -+ -+ If the file descriptor was closed or replaced, open a new file descriptor -+ but don't close the old file descriptor: it probably points to something -+ important for some third-party code. */ - static int --dev_urandom_python(char *buffer, Py_ssize_t size) -+dev_urandom(char *buffer, Py_ssize_t size, int raise) - { - int fd; - Py_ssize_t n; -- struct _Py_stat_struct st; --#ifdef PY_GETRANDOM -- int res; --#endif -- -- if (size <= 0) -- return 0; - --#ifdef PY_GETRANDOM -- res = py_getrandom(buffer, size, 1); -- if (res < 0) { -- return -1; -- } -- if (res == 1) { -- return 0; -- } -- /* getrandom() failed with ENOSYS or EPERM, -- fall back on reading /dev/urandom */ --#endif -+ if (raise) { -+ struct _Py_stat_struct st; - -- if (urandom_cache.fd >= 0) { -- /* Does the fd point to the same thing as before? (issue #21207) */ -- if (_Py_fstat_noraise(urandom_cache.fd, &st) -- || st.st_dev != urandom_cache.st_dev -- || st.st_ino != urandom_cache.st_ino) { -- /* Something changed: forget the cached fd (but don't close it, -- since it probably points to something important for some -- third-party code). */ -- urandom_cache.fd = -1; -- } -- } -- if (urandom_cache.fd >= 0) -- fd = urandom_cache.fd; -- else { -- fd = _Py_open("/dev/urandom", O_RDONLY); -- if (fd < 0) { -- if (errno == ENOENT || errno == ENXIO || -- errno == ENODEV || errno == EACCES) -- PyErr_SetString(PyExc_NotImplementedError, -- "/dev/urandom (or equivalent) not found"); -- /* otherwise, keep the OSError exception raised by _Py_open() */ -- return -1; -- } - if (urandom_cache.fd >= 0) { -- /* urandom_fd was initialized by another thread while we were -- not holding the GIL, keep it. */ -- close(fd); -- fd = urandom_cache.fd; -+ /* Does the fd point to the same thing as before? (issue #21207) */ -+ if (_Py_fstat_noraise(urandom_cache.fd, &st) -+ || st.st_dev != urandom_cache.st_dev -+ || st.st_ino != urandom_cache.st_ino) { -+ /* Something changed: forget the cached fd (but don't close it, -+ since it probably points to something important for some -+ third-party code). */ -+ urandom_cache.fd = -1; -+ } - } -+ if (urandom_cache.fd >= 0) -+ fd = urandom_cache.fd; - else { -- if (_Py_fstat(fd, &st)) { -- close(fd); -+ fd = _Py_open("/dev/urandom", O_RDONLY); -+ if (fd < 0) { -+ if (errno == ENOENT || errno == ENXIO || -+ errno == ENODEV || errno == EACCES) { -+ PyErr_SetString(PyExc_NotImplementedError, -+ "/dev/urandom (or equivalent) not found"); -+ } -+ /* otherwise, keep the OSError exception raised by _Py_open() */ - return -1; - } -+ if (urandom_cache.fd >= 0) { -+ /* urandom_fd was initialized by another thread while we were -+ not holding the GIL, keep it. */ -+ close(fd); -+ fd = urandom_cache.fd; -+ } - else { -- urandom_cache.fd = fd; -- urandom_cache.st_dev = st.st_dev; -- urandom_cache.st_ino = st.st_ino; -+ if (_Py_fstat(fd, &st)) { -+ close(fd); -+ return -1; -+ } -+ else { -+ urandom_cache.fd = fd; -+ urandom_cache.st_dev = st.st_dev; -+ urandom_cache.st_ino = st.st_ino; -+ } - } - } -- } - -- do { -- n = _Py_read(fd, buffer, (size_t)size); -- if (n == -1) { -- return -1; -- } -- if (n == 0) { -- PyErr_Format(PyExc_RuntimeError, -- "Failed to read %zi bytes from /dev/urandom", -- size); -+ do { -+ n = _Py_read(fd, buffer, (size_t)size); -+ if (n == -1) -+ return -1; -+ if (n == 0) { -+ PyErr_Format(PyExc_RuntimeError, -+ "Failed to read %zi bytes from /dev/urandom", -+ size); -+ return -1; -+ } -+ -+ buffer += n; -+ size -= n; -+ } while (0 < size); -+ } -+ else { -+ fd = _Py_open_noraise("/dev/urandom", O_RDONLY); -+ if (fd < 0) { - return -1; - } - -- buffer += n; -- size -= n; -- } while (0 < size); -+ while (0 < size) -+ { -+ do { -+ n = read(fd, buffer, (size_t)size); -+ } while (n < 0 && errno == EINTR); - -+ if (n <= 0) { -+ /* stop on error or if read(size) returned 0 */ -+ close(fd); -+ return -1; -+ } -+ -+ buffer += n; -+ size -= n; -+ } -+ close(fd); -+ } - return 0; - } - -@@ -376,8 +402,8 @@ dev_urandom_close(void) - urandom_cache.fd = -1; - } - } -+#endif /* !MS_WINDOWS */ - --#endif - - /* Fill buffer with pseudo-random bytes generated by a linear congruent - generator (LCG): -@@ -400,31 +426,100 @@ lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size) - } - } - --/* Fill buffer with size pseudo-random bytes from the operating system random -- number generator (RNG). It is suitable for most cryptographic purposes -- except long living private keys for asymmetric encryption. -+/* Read random bytes: - -- Return 0 on success, raise an exception and return -1 on error. */ --int --_PyOS_URandom(void *buffer, Py_ssize_t size) -+ - Return 0 on success -+ - Raise an exception (if raise is non-zero) and return -1 on error -+ -+ Used sources of entropy ordered by preference, preferred source first: -+ -+ - CryptGenRandom() on Windows -+ - getrandom() function (ex: Linux and Solaris): call py_getrandom() -+ - getentropy() function (ex: OpenBSD): call py_getentropy() -+ - /dev/urandom device -+ -+ Read from the /dev/urandom device if getrandom() or getentropy() function -+ is not available or does not work. -+ -+ Prefer getrandom() over getentropy() because getrandom() supports blocking -+ and non-blocking mode and Python requires non-blocking RNG at startup to -+ initialize its hash secret: see the PEP 524. -+ -+ Prefer getrandom() and getentropy() over reading directly /dev/urandom -+ because these functions don't need file descriptors and so avoid ENFILE or -+ EMFILE errors (too many open files): see the issue #18756. -+ -+ Only use RNG running in the kernel. They are more secure because it is -+ harder to get the internal state of a RNG running in the kernel land than a -+ RNG running in the user land. The kernel has a direct access to the hardware -+ and has access to hardware RNG, they are used as entropy sources. -+ -+ Note: the OpenSSL RAND_pseudo_bytes() function does not automatically reseed -+ its RNG on fork(), two child processes (with the same pid) generate the same -+ random numbers: see issue #18747. Kernel RNGs don't have this issue, -+ they have access to good quality entropy sources. -+ -+ If raise is zero: -+ -+ - Don't raise an exception on error -+ - Don't call the Python signal handler (don't call PyErr_CheckSignals()) if -+ a function fails with EINTR: retry directly the interrupted function -+ - Don't release the GIL to call functions. -+*/ -+static int -+pyurandom(void *buffer, Py_ssize_t size, int raise) - { -+#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY) -+ int res; -+#endif -+ - if (size < 0) { -- PyErr_Format(PyExc_ValueError, -- "negative argument not allowed"); -+ if (raise) { -+ PyErr_Format(PyExc_ValueError, -+ "negative argument not allowed"); -+ } - return -1; - } -- if (size == 0) -+ -+ if (size == 0) { - return 0; -+ } - - #ifdef MS_WINDOWS -- return win32_urandom((unsigned char *)buffer, size, 1); --#elif defined(PY_GETENTROPY) -- return py_getentropy(buffer, size, 0); -+ return win32_urandom((unsigned char *)buffer, size, raise); -+#else -+ -+#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY) -+#ifdef PY_GETRANDOM -+ res = py_getrandom(buffer, size, raise); - #else -- return dev_urandom_python((char*)buffer, size); -+ res = py_getentropy(buffer, size, raise); -+#endif -+ if (res < 0) { -+ return -1; -+ } -+ if (res == 1) { -+ return 0; -+ } -+ /* getrandom() or getentropy() function is not available: failed with -+ ENOSYS, EPERM or EAGAIN. Fall back on reading from /dev/urandom. */ -+#endif -+ -+ return dev_urandom(buffer, size, raise); - #endif - } - -+/* Fill buffer with size pseudo-random bytes from the operating system random -+ number generator (RNG). It is suitable for most cryptographic purposes -+ except long living private keys for asymmetric encryption. -+ -+ Return 0 on success. Raise an exception and return -1 on error. */ -+int -+_PyOS_URandom(void *buffer, Py_ssize_t size) -+{ -+ return pyurandom(buffer, size, 1); -+} -+ - void - _PyRandom_Init(void) - { -@@ -463,13 +558,14 @@ _PyRandom_Init(void) - } - } - else { --#ifdef MS_WINDOWS -- (void)win32_urandom(secret, secret_size, 0); --#elif defined(PY_GETENTROPY) -- (void)py_getentropy(secret, secret_size, 1); --#else -- dev_urandom_noraise(secret, secret_size); --#endif -+ int res; -+ -+ /* _PyRandom_Init() is called very early in the Python initialization -+ and so exceptions cannot be used (use raise=0). */ -+ res = pyurandom(secret, secret_size, 0); -+ if (res < 0) { -+ Py_FatalError("failed to get random numbers to initialize Python"); -+ } - } - } - -@@ -481,8 +577,6 @@ _PyRandom_Fini(void) - CryptReleaseContext(hCryptProv, 0); - hCryptProv = 0; - } --#elif defined(PY_GETENTROPY) -- /* nothing to clean */ - #else - dev_urandom_close(); - #endif |