Skip to content

Commit 1fc25a3

Browse files
authored
[3.12] gh-109615: Fix test_tools.test_freeze SRCDIR (#109935) (#109950)
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 1512d6c)
1 parent 3ab9fda commit 1fc25a3

File tree

5 files changed

+60
-50
lines changed

5 files changed

+60
-50
lines changed

Lib/test/libregrtest/main.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,7 @@ def set_temp_dir(self):
747747
if sysconfig.is_python_build():
748748
self.tmp_dir = sysconfig.get_config_var('abs_builddir')
749749
if self.tmp_dir is None:
750-
# bpo-30284: On Windows, only srcdir is available. Using
750+
# gh-74470: On Windows, only srcdir is available. Using
751751
# abs_builddir mostly matters on UNIX when building Python
752752
# out of the source tree, especially when the source tree
753753
# is read only.

Lib/test/support/__init__.py

+26
Original file line numberDiff line numberDiff line change
@@ -2554,3 +2554,29 @@ def adjust_int_max_str_digits(max_digits):
25542554
#Windows doesn't have os.uname() but it doesn't support s390x.
25552555
skip_on_s390x = unittest.skipIf(hasattr(os, 'uname') and os.uname().machine == 's390x',
25562556
'skipped on s390x')
2557+
2558+
_BASE_COPY_SRC_DIR_IGNORED_NAMES = frozenset({
2559+
# SRC_DIR/.git
2560+
'.git',
2561+
# ignore all __pycache__/ sub-directories
2562+
'__pycache__',
2563+
})
2564+
2565+
# Ignore function for shutil.copytree() to copy the Python source code.
2566+
def copy_python_src_ignore(path, names):
2567+
ignored = _BASE_COPY_SRC_DIR_IGNORED_NAMES
2568+
if os.path.basename(path) == 'Doc':
2569+
ignored |= {
2570+
# SRC_DIR/Doc/build/
2571+
'build',
2572+
# SRC_DIR/Doc/venv/
2573+
'venv',
2574+
}
2575+
2576+
# check if we are at the root of the source code
2577+
elif 'Modules' in names:
2578+
ignored |= {
2579+
# SRC_DIR/build/
2580+
'build',
2581+
}
2582+
return ignored

Lib/test/test_support.py

+22
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import stat
88
import subprocess
99
import sys
10+
import sysconfig
1011
import tempfile
1112
import textwrap
1213
import unittest
@@ -765,6 +766,27 @@ def recursive_function(depth):
765766

766767
#self.assertEqual(available, 2)
767768

769+
def test_copy_python_src_ignore(self):
770+
src_dir = sysconfig.get_config_var('srcdir')
771+
src_dir = os.path.abspath(src_dir)
772+
773+
ignored = {'.git', '__pycache__'}
774+
775+
# Source code directory
776+
names = os.listdir(src_dir)
777+
self.assertEqual(support.copy_python_src_ignore(src_dir, names),
778+
ignored | {'build'})
779+
780+
# Doc/ directory
781+
path = os.path.join(src_dir, 'Doc')
782+
self.assertEqual(support.copy_python_src_ignore(path, os.listdir(path)),
783+
ignored | {'build', 'venv'})
784+
785+
# An other directory
786+
path = os.path.join(src_dir, 'Objects')
787+
self.assertEqual(support.copy_python_src_ignore(path, os.listdir(path)),
788+
ignored)
789+
768790
# XXX -follows a list of untested API
769791
# make_legacy_pyc
770792
# is_resource_enabled

Lib/test/test_venv.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
skip_if_broken_multiprocessing_synchronize, verbose,
2222
requires_subprocess, is_emscripten, is_wasi,
2323
requires_venv_with_pip, TEST_HOME_DIR,
24-
requires_resource)
24+
requires_resource, copy_python_src_ignore)
2525
from test.support.os_helper import (can_symlink, EnvironmentVarGuard, rmtree)
2626
import unittest
2727
import venv
@@ -561,6 +561,7 @@ def test_zippath_from_non_installed_posix(self):
561561
platlibdir,
562562
stdlib_zip)
563563
additional_pythonpath_for_non_installed = []
564+
564565
# Copy stdlib files to the non-installed python so venv can
565566
# correctly calculate the prefix.
566567
for eachpath in sys.path:
@@ -577,7 +578,8 @@ def test_zippath_from_non_installed_posix(self):
577578
if os.path.isfile(fn):
578579
shutil.copy(fn, libdir)
579580
elif os.path.isdir(fn):
580-
shutil.copytree(fn, os.path.join(libdir, name))
581+
shutil.copytree(fn, os.path.join(libdir, name),
582+
ignore=copy_python_src_ignore)
581583
else:
582584
additional_pythonpath_for_non_installed.append(
583585
eachpath)

Tools/freeze/test/freeze.py

+7-47
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import os
22
import os.path
3-
import re
43
import shlex
54
import shutil
65
import subprocess
6+
import sysconfig
7+
from test import support
78

89

910
TESTS_DIR = os.path.dirname(__file__)
1011
TOOL_ROOT = os.path.dirname(TESTS_DIR)
11-
SRCDIR = os.path.dirname(os.path.dirname(TOOL_ROOT))
12+
SRCDIR = os.path.abspath(sysconfig.get_config_var('srcdir'))
1213

1314
MAKE = shutil.which('make')
1415
FREEZE = os.path.join(TOOL_ROOT, 'freeze.py')
@@ -75,56 +76,17 @@ def ensure_opt(args, name, value):
7576

7677

7778
def copy_source_tree(newroot, oldroot):
78-
print(f'copying the source tree into {newroot}...')
79+
print(f'copying the source tree from {oldroot} to {newroot}...')
7980
if os.path.exists(newroot):
8081
if newroot == SRCDIR:
8182
raise Exception('this probably isn\'t what you wanted')
8283
shutil.rmtree(newroot)
8384

84-
def ignore_non_src(src, names):
85-
"""Turns what could be a 1000M copy into a 100M copy."""
86-
# Don't copy the ~600M+ of needless git repo metadata.
87-
# source only, ignore cached .pyc files.
88-
subdirs_to_skip = {'.git', '__pycache__'}
89-
if os.path.basename(src) == 'Doc':
90-
# Another potential ~250M+ of non test related data.
91-
subdirs_to_skip.add('build')
92-
subdirs_to_skip.add('venv')
93-
return subdirs_to_skip
94-
95-
shutil.copytree(oldroot, newroot, ignore=ignore_non_src)
85+
shutil.copytree(oldroot, newroot, ignore=support.copy_python_src_ignore)
9686
if os.path.exists(os.path.join(newroot, 'Makefile')):
9787
_run_quiet([MAKE, 'clean'], newroot)
9888

9989

100-
def get_makefile_var(builddir, name):
101-
regex = re.compile(rf'^{name} *=\s*(.*?)\s*$')
102-
filename = os.path.join(builddir, 'Makefile')
103-
try:
104-
infile = open(filename, encoding='utf-8')
105-
except FileNotFoundError:
106-
return None
107-
with infile:
108-
for line in infile:
109-
m = regex.match(line)
110-
if m:
111-
value, = m.groups()
112-
return value or ''
113-
return None
114-
115-
116-
def get_config_var(builddir, name):
117-
python = os.path.join(builddir, 'python')
118-
if os.path.isfile(python):
119-
cmd = [python, '-c',
120-
f'import sysconfig; print(sysconfig.get_config_var("{name}"))']
121-
try:
122-
return _run_stdout(cmd)
123-
except subprocess.CalledProcessError:
124-
pass
125-
return get_makefile_var(builddir, name)
126-
127-
12890
##################################
12991
# freezing
13092

@@ -151,10 +113,8 @@ def prepare(script=None, outdir=None):
151113

152114
# Run configure.
153115
print(f'configuring python in {builddir}...')
154-
cmd = [
155-
os.path.join(srcdir, 'configure'),
156-
*shlex.split(get_config_var(SRCDIR, 'CONFIG_ARGS') or ''),
157-
]
116+
config_args = shlex.split(sysconfig.get_config_var('CONFIG_ARGS') or '')
117+
cmd = [os.path.join(srcdir, 'configure'), *config_args]
158118
ensure_opt(cmd, 'cache-file', os.path.join(outdir, 'python-config.cache'))
159119
prefix = os.path.join(outdir, 'python-installation')
160120
ensure_opt(cmd, 'prefix', prefix)

0 commit comments

Comments
 (0)