diff mbox series

[2/2] python3: compile .pyc at packaging time, remove from manifest

Message ID 20261109143827.3411115-2-ross.burton@arm.com
State New
Headers show
Series [1/2] python3: remove obsolete reformatting of _sysconfigdata*.py | expand

Commit Message

Ross Burton Nov. 9, 2026, 2:38 p.m. UTC
Currently, the manifest lists both .py files and compiled .pyc files.
This results in a large amount of duplication and potential for files to
end up in the wrong package.

Improve this by not installing the .pyc files directly, and instead
using python's compileall module (as upstream's 'make install' does) to
build them at packaging time.  We can do this after the packages have
been split, so the .pyc files are always in the right package.

This means we can remove the cache file logic from create_manifest, and
all of the cached file lists in the manifest itself.

We patch out the standard library compilation at install time to avoid
doing that twice, this is important as the compilation takes ~30s on my
build machine. There is work upstream to make this optional, so we don't
need to carry a patch in the future.

The only change to the end result is that the target sysroot for Python
is now missing the .pyc files.

Signed-off-by: Ross Burton <ross.burton@arm.com>
---
 .../python/python3/create_manifest3.py        |  55 +---
 .../python/python3/no-compile-pyc.patch       |  26 ++
 .../python/python3/python3-manifest.json      | 301 ++----------------
 .../python/python3_3.14.10.bb                 |  63 ++--
 4 files changed, 87 insertions(+), 358 deletions(-)
 create mode 100644 meta/recipes-devtools/python/python3/no-compile-pyc.patch
diff mbox series

Patch

diff --git a/meta/recipes-devtools/python/python3/create_manifest3.py b/meta/recipes-devtools/python/python3/create_manifest3.py
index 288d5ede3a2..5dda382de8f 100644
--- a/meta/recipes-devtools/python/python3/create_manifest3.py
+++ b/meta/recipes-devtools/python/python3/create_manifest3.py
@@ -30,12 +30,6 @@ 
 # 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>
 
 
@@ -77,12 +71,6 @@  def isFolder(value):
     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()
@@ -123,12 +111,8 @@  print_indent('Getting dependencies for package: core', 0)
 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)
+    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
@@ -139,12 +123,8 @@  for coredep in output.split():
 
 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)
+        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']:
@@ -175,12 +155,8 @@  for filedep in old_manifest['core']['files']:
     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)
+        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.
@@ -223,12 +199,10 @@  for pypkg in old_manifest:
     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('--------------------------')
@@ -334,7 +308,7 @@  for pypkg in old_manifest:
                     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']:
+                            for folder_dep in old_manifest[pypkg_with_folder]['files']:
                                 if folder_dep == folder:
                                     print ('%s directory found in %s' % (folder, pypkg_with_folder))
                                     folderFound = True
@@ -351,16 +325,13 @@  for pypkg in old_manifest:
 
             # 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']:
+            if pymodule_dep not in new_manifest[pypkg]['files']:
                 # 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)
+                    new_manifest[pypkg]['files'].append(pymodule_dep)
 
                     # Check for repeated files
                     if pymodule_dep not in allfiles:
@@ -378,7 +349,7 @@  for pypkg in old_manifest:
                     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']:
+                        if pymodule_dep in old_manifest[possible_rdep]['files']:
                             # 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']:
@@ -393,10 +364,7 @@  for pypkg in old_manifest:
                       # 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)
+                        new_manifest[pypkg]['files'].append(pymodule_dep)
                         if pymodule_dep.endswith('*'):
                             wildcards.append(pymodule_dep)
                         if pymodule_dep not in allfiles:
@@ -423,7 +391,6 @@  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
diff --git a/meta/recipes-devtools/python/python3/no-compile-pyc.patch b/meta/recipes-devtools/python/python3/no-compile-pyc.patch
new file mode 100644
index 00000000000..e95458f8a51
--- /dev/null
+++ b/meta/recipes-devtools/python/python3/no-compile-pyc.patch
@@ -0,0 +1,26 @@ 
+Don't compile the standard library to .pyc files, we'll do that at packaging instead.
+
+Upstream-Status: Inappropriate [https://github.com/python/cpython/issues/160835]
+Signed-off-by: Ross Burton <ross.burton@arm.com>
+
+diff --git i/Makefile.pre.in w/Makefile.pre.in
+index 3d12153cb6c..b32eef4810a 100644
+--- i/Makefile.pre.in
++++ w/Makefile.pre.in
+@@ -2829,16 +2829,6 @@ libinstall:	all $(srcdir)/Modules/xxmodule.c
+ 		echo "Applying app store compliance patch"; \
+ 		patch --force --reject-file "$(abs_builddir)/app-store-compliance.rej" --strip 2 --directory "$(DESTDIR)$(LIBDEST)" --input "$(abs_srcdir)/$(APP_STORE_COMPLIANCE_PATCH)" || true ; \
+ 	fi
+-	@ # Build PYC files for the 3 optimization levels (0, 1, 2)
+-	-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
+-		$(PYTHON_FOR_BUILD) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \
+-		-o 0 -o 1 -o 2 $(COMPILEALL_OPTS) -d $(LIBDEST) -f \
+-		-x 'bad_coding|badsyntax|site-packages' \
+-		$(DESTDIR)$(LIBDEST)
+-	-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
+-		$(PYTHON_FOR_BUILD) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \
+-		-o 0 -o 1 -o 2 $(COMPILEALL_OPTS) -d $(LIBDEST)/site-packages -f \
+-		-x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
+ 
+ # bpo-21536: Misc/python-config.sh is generated in the build directory
+ # from $(srcdir)Misc/python-config.sh.in.
diff --git a/meta/recipes-devtools/python/python3/python3-manifest.json b/meta/recipes-devtools/python/python3/python3-manifest.json
index 50fdf5d0eae..4cfbbf978d1 100644
--- a/meta/recipes-devtools/python/python3/python3-manifest.json
+++ b/meta/recipes-devtools/python/python3/python3-manifest.json
@@ -100,8 +100,7 @@ 
             "${libdir}/python${PYTHON_MAJMIN}/*/tests",
             "${libdir}/python${PYTHON_MAJMIN}/idlelib/idle_test/",
             "${libdir}/python${PYTHON_MAJMIN}/test"
-        ],
-        "cached": []
+        ]
     },
     "asyncio": {
         "summary": "Python Asynchronous I/O",
@@ -118,8 +117,7 @@ 
             "${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",
@@ -128,9 +126,6 @@ 
         ],
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/wave.py"
-        ],
-        "cached": [
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/wave.*.pyc"
         ]
     },
     "codecs": {
@@ -140,8 +135,7 @@ 
         ],
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_multibytecodec.*.so"
-        ],
-        "cached": []
+        ]
     },
     "compile": {
         "summary": "Python bytecode compilation support",
@@ -152,11 +146,6 @@ 
             "${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": {
@@ -170,10 +159,6 @@ 
             "${libdir}/python${PYTHON_MAJMIN}/zipfile/",
             "${libdir}/python${PYTHON_MAJMIN}/compression/",
             "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_zstd.*.so"
-        ],
-        "cached": [
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/gzip.*.pyc",
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/tarfile.*.pyc"
         ]
     },
     "core": {
@@ -322,112 +307,6 @@ 
             "${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__/_ast_unparse.*.pyc",
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/_bootlocale.*.pyc",
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/_collections_abc.*.pyc",
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/_colorize.*.pyc",
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/_compression.*.pyc",
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/_markupbase.*.pyc",
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/_opcode_metadata.*.pyc",
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/_py_warnings.*.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__/annotationlib.*.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__/glob.*.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}/__pycache__/zipimport.*.pyc",
-            "${libdir}/python${PYTHON_MAJMIN}/_pyrepl/__pycache__",
-            "${libdir}/python${PYTHON_MAJMIN}/_pyrepl/__pycache__/pager.*.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}/pathlib/__pycache__",
-            "${libdir}/python${PYTHON_MAJMIN}/pathlib/__pycache__/_abc.*.pyc",
-            "${libdir}/python${PYTHON_MAJMIN}/pathlib/__pycache__/_local.*.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}/sysconfig/__pycache__",
-            "${libdir}/python${PYTHON_MAJMIN}/urllib/__pycache__",
-            "${libdir}/python${PYTHON_MAJMIN}/urllib/__pycache__/parse.*.pyc"
         ]
     },
     "crypt": {
@@ -443,9 +322,6 @@ 
             "${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__/hashlib.*.pyc"
         ]
     },
     "ctypes": {
@@ -459,8 +335,7 @@ 
             "${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",
@@ -471,8 +346,7 @@ 
             "${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",
@@ -484,11 +358,6 @@ 
             "${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": {
@@ -499,8 +368,7 @@ 
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/dbm",
             "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_dbm.*.so"
-        ],
-        "cached": []
+        ]
     },
     "debugger": {
         "summary": "Python debugger",
@@ -513,14 +381,9 @@ 
         "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",
@@ -546,9 +409,6 @@ 
         ],
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/difflib.py"
-        ],
-        "cached": [
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/difflib.*.pyc"
         ]
     },
     "doctest": {
@@ -564,9 +424,6 @@ 
         ],
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/doctest.py"
-        ],
-        "cached": [
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/doctest.*.pyc"
         ]
     },
     "email": {
@@ -583,9 +440,6 @@ 
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/email",
             "${libdir}/python${PYTHON_MAJMIN}/imaplib.py"
-        ],
-        "cached": [
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/imaplib.*.pyc"
         ]
     },
     "ensurepip": {
@@ -595,8 +449,7 @@ 
         ],
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/ensurepip/"
-        ],
-        "cached": []
+        ]
     },
     "fcntl": {
         "summary": "Python's fcntl interface",
@@ -605,8 +458,7 @@ 
         ],
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/fcntl.*.so"
-        ],
-        "cached": []
+        ]
     },
     "gdbm": {
         "summary": "Python GNU database support",
@@ -615,8 +467,7 @@ 
         ],
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_gdbm.*.so"
-        ],
-        "cached": []
+        ]
     },
     "html": {
         "summary": "Python HTML processing support",
@@ -625,8 +476,7 @@ 
         ],
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/html"
-        ],
-        "cached": []
+        ]
     },
     "idle": {
         "summary": "Python Integrated Development Environment",
@@ -636,8 +486,7 @@ 
         "files": [
             "${bindir}/idle*",
             "${libdir}/python${PYTHON_MAJMIN}/idlelib"
-        ],
-        "cached": []
+        ]
     },
     "image": {
         "summary": "Python graphical image handling",
@@ -646,9 +495,6 @@ 
         ],
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/colorsys.py"
-        ],
-        "cached": [
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/colorsys.*.pyc"
         ]
     },
     "io": {
@@ -666,12 +512,6 @@ 
             "${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__/socket.*.pyc",
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/ssl.*.pyc",
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/tempfile.*.pyc"
         ]
     },
     "json": {
@@ -682,8 +522,7 @@ 
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/json",
             "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_json.*.so"
-        ],
-        "cached": []
+        ]
     },
     "logging": {
         "summary": "Python logging support",
@@ -697,8 +536,7 @@ 
         ],
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/logging"
-        ],
-        "cached": []
+        ]
     },
     "mailbox": {
         "summary": "Python mailbox format support",
@@ -714,9 +552,6 @@ 
         ],
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/mailbox.py"
-        ],
-        "cached": [
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/mailbox.*.pyc"
         ]
     },
     "math": {
@@ -728,9 +563,6 @@ 
             "${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": {
@@ -740,9 +572,6 @@ 
         ],
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/quopri.py"
-        ],
-        "cached": [
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/quopri.*.pyc"
         ]
     },
     "mmap": {
@@ -752,11 +581,9 @@ 
         ],
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/mmap.*.so"
-        ],
-        "cached": []
+        ]
     },
     "modules": {
-        "cached": [],
         "files": [],
         "rdepends": [
             "asyncio",
@@ -832,8 +659,7 @@ 
             "${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",
@@ -860,16 +686,6 @@ 
             "${libdir}/python${PYTHON_MAJMIN}/smtplib.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__/poplib.*.pyc",
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/secrets.*.pyc",
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/smtplib.*.pyc",
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/uuid.*.pyc"
         ]
     },
     "netserver": {
@@ -880,9 +696,6 @@ 
         ],
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/socketserver.py"
-        ],
-        "cached": [
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/socketserver.*.pyc"
         ]
     },
     "numbers": {
@@ -898,13 +711,6 @@ 
             "${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": {
@@ -918,12 +724,6 @@ 
             "${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": {
@@ -931,8 +731,7 @@ 
         "rdepends": [
             "core"
         ],
-        "files": [],
-        "cached": []
+        "files": []
     },
     "plistlib": {
         "summary": "Generate and parse Mac OS X .plist files",
@@ -943,9 +742,6 @@ 
         ],
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/plistlib.py"
-        ],
-        "cached": [
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/plistlib.*.pyc"
         ]
     },
     "pprint": {
@@ -955,9 +751,6 @@ 
         ],
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/pprint.py"
-        ],
-        "cached": [
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/pprint.*.pyc"
         ]
     },
     "profile": {
@@ -970,11 +763,6 @@ 
             "${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": {
@@ -986,9 +774,6 @@ 
             "${bindir}/pydoc*",
             "${libdir}/python${PYTHON_MAJMIN}/pydoc.py",
             "${libdir}/python${PYTHON_MAJMIN}/pydoc_data"
-        ],
-        "cached": [
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/pydoc.*.pyc"
         ]
     },
     "resource": {
@@ -998,8 +783,7 @@ 
         ],
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/resource.*.so"
-        ],
-        "cached": []
+        ]
     },
     "shell": {
         "summary": "Python shell-like functionality",
@@ -1010,10 +794,6 @@ 
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/cmd.py",
             "${libdir}/python${PYTHON_MAJMIN}/shlex.py"
-        ],
-        "cached": [
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/cmd.*.pyc",
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/shlex.*.pyc"
         ]
     },
     "sqlite3": {
@@ -1025,8 +805,7 @@ 
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_sqlite3.*.so",
             "${libdir}/python${PYTHON_MAJMIN}/sqlite3"
-        ],
-        "cached": []
+        ]
     },
     "statistics": {
         "summary": "Basic statistics module",
@@ -1038,9 +817,6 @@ 
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_statistics.*.so",
             "${libdir}/python${PYTHON_MAJMIN}/statistics.py"
-        ],
-        "cached": [
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/statistics.*.pyc"
         ]
     },
     "stringold": {
@@ -1051,8 +827,7 @@ 
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/string",
             "${libdir}/python${PYTHON_MAJMIN}/string/__pycache__"
-        ],
-        "cached": []
+        ]
     },
     "syslog": {
         "summary": "Python syslog interface",
@@ -1061,8 +836,7 @@ 
         ],
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/syslog.*.so"
-        ],
-        "cached": []
+        ]
     },
     "terminal": {
         "summary": "Python terminal controlling support",
@@ -1073,10 +847,6 @@ 
         "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": {
@@ -1088,10 +858,6 @@ 
             "${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": {
@@ -1101,8 +867,7 @@ 
         ],
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/tkinter"
-        ],
-        "cached": []
+        ]
     },
     "tomllib": {
         "summary": "Provides an interface for parsing TOML",
@@ -1111,8 +876,7 @@ 
         ],
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/tomllib/"
-        ],
-        "cached": []
+        ]
     },
     "unittest": {
         "summary": "Python unit testing framework",
@@ -1131,8 +895,7 @@ 
             "${libdir}/python${PYTHON_MAJMIN}/unittest",
             "${libdir}/python${PYTHON_MAJMIN}/unittest/",
             "${libdir}/python${PYTHON_MAJMIN}/unittest/__pycache__"
-        ],
-        "cached": []
+        ]
     },
     "unixadmin": {
         "summary": "Python Unix administration support",
@@ -1142,9 +905,6 @@ 
         ],
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/getpass.py"
-        ],
-        "cached": [
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/getpass.*.pyc"
         ]
     },
     "venv": {
@@ -1157,8 +917,7 @@ 
         "files": [
             "${bindir}/pyvenv*",
             "${libdir}/python${PYTHON_MAJMIN}/venv"
-        ],
-        "cached": []
+        ]
     },
     "xml": {
         "summary": "Python basic XML support",
@@ -1169,8 +928,7 @@ 
             "${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",
@@ -1192,8 +950,7 @@ 
         "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",
@@ -1203,9 +960,6 @@ 
         ],
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/zipapp.py"
-        ],
-        "cached": [
-            "${libdir}/python${PYTHON_MAJMIN}/__pycache__/zipapp.*.pyc"
         ]
     },
     "zoneinfo": {
@@ -1217,7 +971,6 @@ 
         "files": [
             "${libdir}/python${PYTHON_MAJMIN}/lib-dynload/_zoneinfo.*.so",
             "${libdir}/python${PYTHON_MAJMIN}/zoneinfo"
-        ],
-        "cached": []
+        ]
     }
 }
diff --git a/meta/recipes-devtools/python/python3_3.14.10.bb b/meta/recipes-devtools/python/python3_3.14.10.bb
index 28e67330d1a..c57868bf709 100644
--- a/meta/recipes-devtools/python/python3_3.14.10.bb
+++ b/meta/recipes-devtools/python/python3_3.14.10.bb
@@ -24,6 +24,7 @@  SRC_URI = "http://www.python.org/ftp/python/${PV}/Python-${PV}.tar.xz \
            file://0001-gh-146207-Add-support-for-OpenSSL-4.0.0.patch \
            file://0002-gh-148292-Update-_ssl._SSLSocket-for-OpenSSL-4.patch \
            file://0003-gh-148292-Remove-shutdown-test-in-test_ssl.test_got_eof.patch \
+           file://no-compile-pyc.patch \
            "
 SRC_URI:append:class-native = " \
            file://0001-Lib-sysconfig.py-use-prefix-value-from-build-configu.patch \
@@ -135,24 +136,10 @@  EOF
 
 CPPFLAGS += "-I${STAGING_INCDIR}/ncursesw -I${STAGING_INCDIR}/uuid"
 
-# COMPILEALL_OPTS= ensures that .pyc are not compiled in parallel
-# This was found to lock up builds, break reproducibility, and produce strange file ownership
-# races.
-#
-# The upstream commit introducing the change was:
-# https://github.com/python/cpython/commit/1a2dd82f56bd813aacc570e172cefe55a8a41504
-#
-# The build lock up issue is reported here:
-# https://bugs.python.org/issue45945
-#
-# The repro failures are documented here:
-# https://autobuilder.yocto.io/pub/repro-fail/oe-reproducible-20211130-yr_o1a8d/packages/diff-html/
-
 EXTRA_OEMAKE = '\
   STAGING_LIBDIR=${STAGING_LIBDIR} \
   STAGING_INCDIR=${STAGING_INCDIR} \
   LIB=${baselib} \
-  COMPILEALL_OPTS= \
 '
 
 # Generate a Profile Guided Optimisation wrapper script that uses qemu-user for
@@ -192,15 +179,6 @@  do_install:append:class-native() {
         # buffer is 128 bytes long).
         ln -s python3-native/python3 ${D}${bindir}/nativepython3
 
-        # Remove the opt-1.pyc and opt-2.pyc files. There are over 3,000 of them
-        # and the overhead in each recipe-sysroot-native isn't worth it, particularly
-        # when they're only used for python called with -O or -OO.
-        #find ${D} -name *opt-*.pyc -delete
-        # Remove all pyc files. There are a ton of them and it is probably faster to let
-        # python create the ones it wants at runtime rather than manage in the sstate
-        # tarballs and sysroot creation.
-        find ${D} -name *.pyc -delete
-
         # Nothing should be looking into ${B} for python3-native
         sed -i -e 's:${B}:/build/path/unavailable/:g' \
                 ${D}/${libdir}/python${PYTHON_MAJMIN}/config-${PYTHON_MAJMIN}${PYTHON_ABI}*/Makefile
@@ -213,8 +191,6 @@  do_install:append:class-native() {
 }
 
 do_install:append() {
-        rm -f ${D}${libdir}/python${PYTHON_MAJMIN}/__pycache__/_sysconfigdata*.cpython*
-
         mkdir -p ${D}${libdir}/python-sysconfigdata
         sysconfigfile=`find ${D} -name _sysconfig*.py`
         sed -i  \
@@ -229,11 +205,6 @@  do_install:append() {
                 -e "s,${B},/build/path/unavailable/,g" \
                 $sysconfigfile
         cp $sysconfigfile ${D}${libdir}/python-sysconfigdata/_sysconfigdata.py
-
-        # Remove the opt-1.pyc and opt-2.pyc files. They effectively waste space on embedded
-        # style targets as they're only used when python is called with the -O or -OO options
-        # which is rare.
-        find ${D} -name *opt-*.pyc -delete
 }
 
 do_install:append:class-nativesdk () {
@@ -353,6 +324,9 @@  provide_target_config_script() {
         install -d ${SYSROOT_DESTDIR}${prefix}/python-target-config/
         install ${D}/${bindir}/python3-config ${SYSROOT_DESTDIR}/${prefix}/python-target-config/
         install ${D}/${bindir}/python${PYTHON_MAJMIN}-config ${SYSROOT_DESTDIR}/${prefix}/python-target-config/
+        # Compile the sysconfigdata in the target sysroot as it will be generated if
+        # python3targetconfig is inherited.
+        python3 -mcompileall ${SYSROOT_DESTDIR}${libdir}/python${PYTHON_MAJMIN}/_sysconfigdata*.py -s ${SYSROOT_DESTDIR} -p /
 }
 SYSROOT_DIRS += "${prefix}/python-target-config/"
 
@@ -385,11 +359,6 @@  py_package_preprocess () {
                 ${PKGD}/${libdir}/python${PYTHON_MAJMIN}/_sysconfig_vars*.json \
                 ${PKGD}/${bindir}/python${PYTHON_MAJMIN}-config
 
-        # Recompile _sysconfigdata after modifying it
-        for c in ${PKGD}/${libdir}/python${PYTHON_MAJMIN}/_sysconfigdata*.py; do
-            python3 -mcompileall $c -s ${PKGD} -p /
-        done
-
         mv ${PKGD}/${bindir}/python${PYTHON_MAJMIN}-config ${PKGD}/${bindir}/python${PYTHON_MAJMIN}-config-${MULTILIB_SUFFIX}
 
         #Remove the unneeded copy of target sysconfig data
@@ -399,9 +368,28 @@  py_package_preprocess () {
         sed -i -e 's:${BUILD_ARCH}-${HOST_OS}:${HOST_ARCH}-${HOST_OS}:g' ${PKGD}/${libdir}/python${PYTHON_MAJMIN}/build-details.json
 }
 
+# Compile the .py files in PKGDEST to .pyc. This is done during do_package so the .pyc files
+# are always packaged with the .py.
+py_compile_py() {
+        if [ "${INCLUDE_PYCS}" != "0" ]; then
+            bbnote Compiling python bytecode...
+            # Need to do each package individually so we can strip the correct path prefix
+            for dir in $(find ${PKGDEST} -type d -maxdepth 1); do
+                # Currently compileall isn't deterministic when ran
+                # in parallel so we can't yet pass -j.
+                # https://github.com/python/cpython/issues/129724
+                nativepython3 -mcompileall \
+                    -f -s $dir -p / -x 'bad_coding|badsyntax' \
+                    $dir
+            done
+        fi
+}
+PACKAGESPLITFUNCS += "py_compile_py"
+
 # We want bytecode precompiled .py files (.pyc's) by default
 # but the user may set it on their own conf
 INCLUDE_PYCS ?= "1"
+INCLUDE_PYCS:class-native = "0"
 
 python(){
     import collections, json
@@ -452,11 +440,6 @@  python(){
         for value in python_manifest[key]['files']:
             d.appendVar('FILES:' + pypackage, ' ' + value)
 
-        # Add cached files
-        if include_pycs == '1':
-            for value in python_manifest[key]['cached']:
-                    d.appendVar('FILES:' + pypackage, ' ' + value)
-
         for value in python_manifest[key]['rdepends']:
             # Make it work with or without $PN
             if '${PN}' in value: