summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/compileall.py12
-rw-r--r--Lib/test/test_compileall.py23
-rw-r--r--Misc/NEWS.d/next/Library/2023-08-30-19-10-35.gh-issue-105931.Lpwve8.rst8
3 files changed, 37 insertions, 6 deletions
diff --git a/Lib/compileall.py b/Lib/compileall.py
index d394156..9b53086 100644
--- a/Lib/compileall.py
+++ b/Lib/compileall.py
@@ -172,13 +172,13 @@ def compile_file(fullname, ddir=None, force=False, rx=None, quiet=0,
if stripdir is not None:
fullname_parts = fullname.split(os.path.sep)
stripdir_parts = stripdir.split(os.path.sep)
- ddir_parts = list(fullname_parts)
- for spart, opart in zip(stripdir_parts, fullname_parts):
- if spart == opart:
- ddir_parts.remove(spart)
-
- dfile = os.path.join(*ddir_parts)
+ if stripdir_parts != fullname_parts[:len(stripdir_parts)]:
+ if quiet < 2:
+ print("The stripdir path {!r} is not a valid prefix for "
+ "source path {!r}; ignoring".format(stripdir, fullname))
+ else:
+ dfile = os.path.join(*fullname_parts[len(stripdir_parts):])
if prependdir is not None:
if dfile is None:
diff --git a/Lib/test/test_compileall.py b/Lib/test/test_compileall.py
index 9cd92ad..83a9532 100644
--- a/Lib/test/test_compileall.py
+++ b/Lib/test/test_compileall.py
@@ -362,6 +362,29 @@ class CompileallTestsBase:
str(err, encoding=sys.getdefaultencoding())
)
+ def test_strip_only_invalid(self):
+ fullpath = ["test", "build", "real", "path"]
+ path = os.path.join(self.directory, *fullpath)
+ os.makedirs(path)
+ script = script_helper.make_script(path, "test", "1 / 0")
+ bc = importlib.util.cache_from_source(script)
+ stripdir = os.path.join(self.directory, *(fullpath[:2] + ['fake']))
+ compileall.compile_dir(path, quiet=True, stripdir=stripdir)
+ rc, out, err = script_helper.assert_python_failure(bc)
+ expected_not_in = os.path.join(self.directory, *fullpath[2:])
+ self.assertIn(
+ path,
+ str(err, encoding=sys.getdefaultencoding())
+ )
+ self.assertNotIn(
+ expected_not_in,
+ str(err, encoding=sys.getdefaultencoding())
+ )
+ self.assertNotIn(
+ stripdir,
+ str(err, encoding=sys.getdefaultencoding())
+ )
+
def test_prepend_only(self):
fullpath = ["test", "build", "real", "path"]
path = os.path.join(self.directory, *fullpath)
diff --git a/Misc/NEWS.d/next/Library/2023-08-30-19-10-35.gh-issue-105931.Lpwve8.rst b/Misc/NEWS.d/next/Library/2023-08-30-19-10-35.gh-issue-105931.Lpwve8.rst
new file mode 100644
index 0000000..4e769ec
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-08-30-19-10-35.gh-issue-105931.Lpwve8.rst
@@ -0,0 +1,8 @@
+Change :mod:`compileall` to only strip the stripdir prefix from the full path
+recorded in the compiled ``.pyc`` file, when the prefix matches the start of
+the full path in its entirety. When the prefix does not match, no stripping is
+performed and a warning to this effect is displayed.
+
+Previously all path components of the stripdir prefix that matched the full
+path were removed, while those that did not match were left alone (including
+ones interspersed between matching components).