]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.11] gh-109615: Fix test_tools.test_freeze SRCDIR (#109935) (#109951)
authorVictor Stinner <vstinner@python.org>
Wed, 27 Sep 2023 08:59:02 +0000 (10:59 +0200)
committerGitHub <noreply@github.com>
Wed, 27 Sep 2023 08:59:02 +0000 (08:59 +0000)
gh-109615: Fix test_tools.test_freeze SRCDIR (#109935)

Fix copy_source_tree() function of test_tools.test_freeze:

* Don't copy SRC_DIR/build/ anymore. This directory is modified by
  other tests running in parallel.
* Add test.support.copy_python_src_ignore().
* Use sysconfig to get the source directory.
* Use sysconfig.get_config_var() to get CONFIG_ARGS variable.

(cherry picked from commit 1512d6c6ee2a770afb339bbb74c1b990116f7f89)

Lib/test/libregrtest/main.py
Lib/test/support/__init__.py
Lib/test/test_support.py
Lib/test/test_venv.py
Tools/freeze/test/freeze.py

index 6e6423e156781bd2f955c29f6ae735db33887c0a..e4e65e943d67bc51079dffcd581f0e6dfaf0336b 100644 (file)
@@ -731,7 +731,7 @@ class Regrtest:
             if sysconfig.is_python_build():
                 self.tmp_dir = sysconfig.get_config_var('abs_builddir')
                 if self.tmp_dir is None:
-                    # bpo-30284: On Windows, only srcdir is available. Using
+                    # gh-74470: On Windows, only srcdir is available. Using
                     # abs_builddir mostly matters on UNIX when building Python
                     # out of the source tree, especially when the source tree
                     # is read only.
index b4fa727aae3413ac424f7ded6724963e032fe153..2c6b22fdee5a21a7cd1d84e741f0593a4e2fc74f 100644 (file)
@@ -2324,3 +2324,29 @@ def adjust_int_max_str_digits(max_digits):
         yield
     finally:
         sys.set_int_max_str_digits(current)
+
+_BASE_COPY_SRC_DIR_IGNORED_NAMES = frozenset({
+    # SRC_DIR/.git
+    '.git',
+    # ignore all __pycache__/ sub-directories
+    '__pycache__',
+})
+
+# Ignore function for shutil.copytree() to copy the Python source code.
+def copy_python_src_ignore(path, names):
+    ignored = _BASE_COPY_SRC_DIR_IGNORED_NAMES
+    if os.path.basename(path) == 'Doc':
+        ignored |= {
+            # SRC_DIR/Doc/build/
+            'build',
+            # SRC_DIR/Doc/venv/
+            'venv',
+        }
+
+    # check if we are at the root of the source code
+    elif 'Modules' in names:
+        ignored |= {
+            # SRC_DIR/build/
+            'build',
+        }
+    return ignored
index 54e532064740f33c42f20fac254f5774ee09e11b..a6b241e4a82b7653781845c14347aaee243a733a 100644 (file)
@@ -7,6 +7,7 @@ import socket
 import stat
 import subprocess
 import sys
+import sysconfig
 import tempfile
 import textwrap
 import time
@@ -777,6 +778,27 @@ class TestSupport(unittest.TestCase):
 
         #self.assertEqual(available, 2)
 
+    def test_copy_python_src_ignore(self):
+        src_dir = sysconfig.get_config_var('srcdir')
+        src_dir = os.path.abspath(src_dir)
+
+        ignored = {'.git', '__pycache__'}
+
+        # Source code directory
+        names = os.listdir(src_dir)
+        self.assertEqual(support.copy_python_src_ignore(src_dir, names),
+                         ignored | {'build'})
+
+        # Doc/ directory
+        path = os.path.join(src_dir, 'Doc')
+        self.assertEqual(support.copy_python_src_ignore(path, os.listdir(path)),
+                         ignored | {'build', 'venv'})
+
+        # An other directory
+        path = os.path.join(src_dir, 'Objects')
+        self.assertEqual(support.copy_python_src_ignore(path, os.listdir(path)),
+                         ignored)
+
     # XXX -follows a list of untested API
     # make_legacy_pyc
     # is_resource_enabled
index a37c6b7163f2d288bd3dd3287b5b5a70b892ca23..884ac3ac567c07cfbf538e7400b81f2615098b34 100644 (file)
@@ -21,7 +21,7 @@ from test.support import (captured_stdout, captured_stderr, requires_zlib,
                           skip_if_broken_multiprocessing_synchronize, verbose,
                           requires_subprocess, is_emscripten, is_wasi,
                           requires_venv_with_pip, TEST_HOME_DIR,
-                          requires_resource)
+                          requires_resource, copy_python_src_ignore)
 from test.support.os_helper import (can_symlink, EnvironmentVarGuard, rmtree)
 import unittest
 import venv
@@ -563,12 +563,6 @@ class BasicTest(BaseTest):
                                     stdlib_zip)
         additional_pythonpath_for_non_installed = []
 
-        # gh-109748: Don't copy __pycache__/ sub-directories, because they can
-        # be modified by other Python tests running in parallel.
-        ignored_names = {'__pycache__'}
-        def ignore_pycache(src, names):
-            return ignored_names
-
         # Copy stdlib files to the non-installed python so venv can
         # correctly calculate the prefix.
         for eachpath in sys.path:
@@ -586,7 +580,7 @@ class BasicTest(BaseTest):
                         shutil.copy(fn, libdir)
                     elif os.path.isdir(fn):
                         shutil.copytree(fn, os.path.join(libdir, name),
-                                        ignore=ignore_pycache)
+                                        ignore=copy_python_src_ignore)
             else:
                 additional_pythonpath_for_non_installed.append(
                     eachpath)
index f6a5adb4519fdb041675d433c323daf397f00fae..bb15941464e3d1eccbcfd2d7da509bcda8fe0d1d 100644 (file)
@@ -1,14 +1,15 @@
 import os
 import os.path
-import re
 import shlex
 import shutil
 import subprocess
+import sysconfig
+from test import support
 
 
 TESTS_DIR = os.path.dirname(__file__)
 TOOL_ROOT = os.path.dirname(TESTS_DIR)
-SRCDIR = os.path.dirname(os.path.dirname(TOOL_ROOT))
+SRCDIR = os.path.abspath(sysconfig.get_config_var('srcdir'))
 
 MAKE = shutil.which('make')
 FREEZE = os.path.join(TOOL_ROOT, 'freeze.py')
@@ -75,56 +76,17 @@ def ensure_opt(args, name, value):
 
 
 def copy_source_tree(newroot, oldroot):
-    print(f'copying the source tree into {newroot}...')
+    print(f'copying the source tree from {oldroot} to {newroot}...')
     if os.path.exists(newroot):
         if newroot == SRCDIR:
             raise Exception('this probably isn\'t what you wanted')
         shutil.rmtree(newroot)
 
-    def ignore_non_src(src, names):
-        """Turns what could be a 1000M copy into a 100M copy."""
-        # Don't copy the ~600M+ of needless git repo metadata.
-        # source only, ignore cached .pyc files.
-        subdirs_to_skip = {'.git', '__pycache__'}
-        if os.path.basename(src) == 'Doc':
-            # Another potential ~250M+ of non test related data.
-            subdirs_to_skip.add('build')
-            subdirs_to_skip.add('venv')
-        return subdirs_to_skip
-
-    shutil.copytree(oldroot, newroot, ignore=ignore_non_src)
+    shutil.copytree(oldroot, newroot, ignore=support.copy_python_src_ignore)
     if os.path.exists(os.path.join(newroot, 'Makefile')):
         _run_quiet([MAKE, 'clean'], newroot)
 
 
-def get_makefile_var(builddir, name):
-    regex = re.compile(rf'^{name} *=\s*(.*?)\s*$')
-    filename = os.path.join(builddir, 'Makefile')
-    try:
-        infile = open(filename, encoding='utf-8')
-    except FileNotFoundError:
-        return None
-    with infile:
-        for line in infile:
-            m = regex.match(line)
-            if m:
-                value, = m.groups()
-                return value or ''
-    return None
-
-
-def get_config_var(builddir, name):
-    python = os.path.join(builddir, 'python')
-    if os.path.isfile(python):
-        cmd = [python, '-c',
-               f'import sysconfig; print(sysconfig.get_config_var("{name}"))']
-        try:
-            return _run_stdout(cmd)
-        except subprocess.CalledProcessError:
-            pass
-    return get_makefile_var(builddir, name)
-
-
 ##################################
 # freezing
 
@@ -151,10 +113,8 @@ def prepare(script=None, outdir=None):
 
     # Run configure.
     print(f'configuring python in {builddir}...')
-    cmd = [
-        os.path.join(srcdir, 'configure'),
-        *shlex.split(get_config_var(srcdir, 'CONFIG_ARGS') or ''),
-    ]
+    config_args = shlex.split(sysconfig.get_config_var('CONFIG_ARGS') or '')
+    cmd = [os.path.join(srcdir, 'configure'), *config_args]
     ensure_opt(cmd, 'cache-file', os.path.join(outdir, 'python-config.cache'))
     prefix = os.path.join(outdir, 'python-installation')
     ensure_opt(cmd, 'prefix', prefix)